我做了一个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_w
和children_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(¤t);
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 的内存,因为一个函数调用中使用的内存在执行完成后不会释放。任何人都可以 Pls 建议内存被变量保留,即使在函数调用返回值之后,即使它们被显式删除以及解决此问题的任何解决方案。
根据问题的格式,很难理解问题,但乍一看,您似乎正在将非错误定位的指针传递给free()
。结果是未定义的行为。
请删除
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 而释放,则行为是未定义的。
另外,您应该参考手册页以获取free()
。
除此之外,对于您情况下的泄漏,您正在释放b->parent
但没有释放嵌套的分配内存以供b->parent
使用。同样,你根本没有释放children_w
和children_b
。它们都需要得到适当的照顾。
在void del(Board* b)()
函数中,你释放了free(b->parent);
,这是一个链表,但你还有另外两个链表struct Board* children_w;
和struct Board* children_b;
,也需要正确释放。在链表中,您必须使用 free()
显式访问并删除每个节点。在代码中查看此方面。从上面的代码中不清楚这些链表。
Sourav 是正确的,除非你明确地为它们分配了内存,否则你不会释放 Board 的参数,否则会导致不良影响(你可能会释放随机内存并在内存中留下悬空指针)。我建议你运行瓦尔格林德:valgrind --leak-check=yes myprog arg1 arg2
并阅读 http://valgrind.org/docs/manual/quick-start.html 以获取更多信息