【问题标题】:Memory leak in C ProgramC 程序中的内存泄漏
【发布时间】:2015-01-14 05:26:43
【问题描述】:

我制作了一个 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;

ListofMoveBoard* 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 内存,因为在一个函数调用中使用的内存在执行完成后没有被释放。即使在函数调用返回值之后,即使它们被显式删除以及解决此问题的任何解决方案,任何人都可以通过内存保留变量。

【问题讨论】:

  • realloc() / free() in c++?不是一个好方法。
  • 你在哪里释放分配的内存?
  • 您似乎懒得在发布之前格式化/预览您的帖子。所以懒得回答了。
  • C 还是 C++?选一个。它只能是一个。

标签: c struct linked-list free


【解决方案1】:

根据您的问题的格式,很难理解这个问题,但乍一看,您似乎将非分配指针传递给 free() 。结果是undefined behaviour

请删除

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

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

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

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

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

另外,您应该参考manual page 获取free()

除此之外,对于您的情况,泄漏,您正在释放b-&gt;parent,但没有释放b-&gt;parent 的嵌套分配内存。同样,您根本没有释放children_wchildren_b。他们都需要妥善照顾。

【讨论】:

  • 问题仍然存在,因为函数中本地定义的变量应该在函数执行完成后自行释放,因此如果一个函数调用成功执行,它可以迭代任意次数。
  • @gargi 摆脱未定义的行为,你就会有你的目标。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 2018-10-09
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      相关资源
      最近更新 更多