C程序中的内存泄漏

时间:2015-01-14 05:26:43

标签: c struct linked-list free

我制作了一个C程序,其中我使用了定义为:

的结构
typedef struct Move{

int from_x; 
int from_y;
int to_x; 
int to_y;
int piece; 
}Move;

typedef struct ListofMove{

Move* array;
int len;
}ListofMove;

typedef struct Board{

int B[8][8];
double value;       
double value_w;
double value_b;
int material_w;    
int material_b;    
int mobility_w;
int mobility_b;
int dev_w;         
int dev_b;
int center_w;
int center_b;
int devArr[4][8]; 
int side;      
ListofMove moves_w;
ListofMove moves_b;
struct Board* children_w;
struct Board* children_b;
int len_w;
int len_b;  
struct Board *parent;
double alpha;
double beta;    
}Board;

使用ListofMove函数添加Board* children_wchildren_b以及realloc()中的数据。main()仅包含针对某些迭代的单个函数调用(此处让我们说30)

int main(){

double BW[4] = {5.689821, 39.038832, 26.088224, 60.491498};
double WW[4] = {82.091284, 83.026237, 46.478279, 49.979957};
int outres, in;

for(in = 0 ; in<20; in++){
   depth = 0; Nply = 0; count = 0;
   outres = gameplay(BW, WW);           
 }

 return 0;      
}

所有变量都在函数gameplay()中本地声明,并在游戏中进行的其他函数调用(通过值调用或按地址调用)进一步使用。使用后,使用函数del(Board* b)delm(Move* m)明确删除所有变量。

int gameplay(double blwght[], double whwght[]){

int i, ind;
Board pre;
Board result;   
Board current;  
Move cur_B, cur_W;

.............
..............
.......

del(&pre);
del(&result);
del(&current);
delm(&cur_B);
delm(&cur_W);   
}

删除功能的定义

 void del(Board* b){

    b->beta = 0; 
    b->alpha = 0;
    b->material_w = 0;
    b->material_b = 0;
    b->mobility_w = 0;
    b->mobility_b = 0;
    b->center_w = 0;
    b->center_b = 0;
    b->dev_w = 0;
    b->dev_b = 0;
    b->value_w = 0;
    b->value_b = 0;
    b->value = 0;
    b->side = 0;

    free(&b->value_w);
    free(&b->value_b);
    free(&b->center_w);
    free(&b->center_b);
    free(&b->dev_w);
    free(&b->dev_b);
    free(&b->mobility_w);
    free(&b->mobility_b);       
    free(&b->material_w);
    free(&b->material_b); 
    free(&b->side);
    free(&b->len_w);
    free(&b->len_b);
    free(&b->alpha);
    free(&b->beta);
    free(b->B);
    free(b->devArr);
    free(b->parent);
    ClearWBoardList(b);
    ClearBBoardList(b);
    ClearMoveList(&b->moves_w);
    ClearMoveList(&b->moves_b);
    free(&b->moves_w.array);
    free(&b->moves_b.array);
    free(&b->moves_w);
    free(&b->moves_b);
 } 

 void delm(Move*  m){

    m->from_x = 0;
    m->from_y = 0;
    m->to_x = 0; 
    m->to_y = 0; 
    m->piece = 0;

    free(&m->from_x);
    free(&m->from_y);
    free(&m->to_x);
    free(&m->to_y);
    free(&m->piece);
  }

问题是甚至在删除变量并且函数调用完全执行几次迭代之后程序崩溃(在我的情况下系统具有3GB RAM的大约14次迭代之后)。检测到的问题是在崩溃之前它使用了大约2GB的内存,因为一个函数调用中使用的内存在执行完成后没有被释放。任何人都可以通过内存建议保留变量,即使在函数调用返回值之后,即使它们被明确删除并且任何解决方案都可以解决这个问题。

3 个答案:

答案 0 :(得分:1)

根据问题的格式,很难理解问题,但初看起来,你似乎已经将非malloced指针传递给free()。结果是undefined behaviour

请删除

free(&b->value_w);
free(&m->from_x);

和剩余编译时分配的变量地址。

根据规则,free() - 仅允许[而非必需]用于动态分配的内存。 OTOH,编译时内存不需要从程序中明确释放。

相关阅读:根据第7.20.3.2节,C99标准,第2段

  

free函数导致ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与calloc,malloc或realloc函数先前返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为未定义。

另外,您应该参考free()的{​​{3}}。

除此之外,对于您的情况中的泄漏,您可以释放b->parent,但不会释放b->parent的嵌套已分配内存。同样,您根本没有释放children_wchildren_b。他们都需要得到妥善照顾。

答案 1 :(得分:0)

void del(Board* b)()功能中,您释放free(b->parent);这是一个链接列表,但您还有两个链接列表struct Board* children_w;struct Board* children_b;,这些列表也需要正确释放。 在链接列表中,您必须使用free()显式地访问和删除每个节点。 在您的代码中查看此方面。从上面的代码中不清楚这些链接列表。

答案 2 :(得分:0)

Sourav是正确的你不会释放Board的参数,除非你为它们明确分配内存,否则会导致不良影响(你可能会释​​放随机内存并在内存中留下悬空指针)。我建议您运行Valgrind:valgrind --leak-check=yes myprog arg1 arg2并阅读http://valgrind.org/docs/manual/quick-start.html以获取更多信息