我正试图在下面的代码中找到内存泄漏。 valgrind给了我这个:
==14160== 1,850 (592 direct, 1,258 indirect) bytes in 9 blocks are definitely lost in loss record 2 of 5
==14160== at 0x4904A06: malloc (vg_replace_malloc.c:149)
==14160== by 0x405B1F: tsCreate (ticket_set.c:55)
==14160== by 0x401ECA: test1TS (main.c:62)
==14160== by 0x40557C: main (main.c:424)
这是函数:
TicketSetStatus tsCreate(TicketSet* t, int n, int c) {
if(t==NULL){
return TS_CANNOT_CREATE;
}
if (n <= 0){
return TS_ILLEGAL_PARAMETER;
}
t->usedTravels = 0;
t->originalTravels = n;
t->cost = c;
t->moneyLeft = n * c;
//Date time is array of travels:
t->dates = malloc(sizeof(DateTime *)* (n)); //todo maybe c99 allows dynamic arrays?
for (int i = 0; i < n; i++) {
t->dates[i] = malloc(sizeof(char)*GOOD_LENGTH+1);
if (t->dates[i] == NULL) {
free( t->dates);
return TS_CANNOT_CREATE;
}
}
return TS_SUCCESS;
}
TicketSetStatus tsDestroy(TicketSet* t, int* moneyLeft) {
if (t == NULL) {
return TS_FAIL;
}
*moneyLeft = (t->cost) * (t->originalTravels-t->usedTravels);
for (int i = 0; i < t->originalTravels; i++){
free(t->dates[i]);
}
free(t->dates);
t=NULL;
return TS_SUCCESS;
}
结构为:
struct TS_element {
int usedTravels;
int originalTravels;
int cost;
DateTime* dates;
int moneyLeft;
};
和
typedef char* DateType
实际上玩免费会使程序更频繁地崩溃,所以只要程序正常运行,我就倾向于使用内存泄漏。
答案 0 :(得分:1)
你是如何使用这个DateTime
数组的?如果您稍后踩踏这些值,您将会泄漏。也许是关于字符串赋值的混淆? 即
char someDateValue[] = "2012-08-15";
t->dates[0] = someDateValue; // Leak -- your allocated string is lost
相反:
strcpy( t->dates[0], someDateValue );
tsCreate
中的错误情况确实存在泄漏:
for (int i = 0; i < n; i++) {
t->dates[i] = malloc(sizeof(char)*GOOD_LENGTH+1);
if (t->dates[i] == NULL) {
free(t->dates); // Leak -- every element up to i-1 is lost
return TS_CANNOT_CREATE;
}
}
在您完成tsDestroy
初始化的数据后,您是否在调用tsCreate
?也许你是在没有清理的情况下从main
回来的。
如果这些都没有帮助,您应该发布其他代码来说明您如何使用数据结构。
答案 1 :(得分:1)
对于至少一个错误,您可以只关注
...
t->dates = malloc(sizeof(DateTime*) * (n)); /* first malloc */
for (int i = 0; i < n; i++) { /* call this loop 1 */
t->dates[i] = malloc(sizeof(char)*GOOD_LENGTH+1); /* second malloc */
if (t->dates[i] == NULL) { /* test for malloc error */
free( t->dates); /* free the base array/list */
return TS_CANNOT_CREATE; /* exit function */
}
}
...
问题是如果第二个malloc
失败,free
只释放基(第一个)malloc。它不释放第二个malloc创建的任何其他内存分配
在循环1中,在前一循环1迭代上。即如果t->dates[i] = malloc(...
在i等于5时失败,则在退出函数之前,不会释放在迭代0到4中分配的内存块。
希望这是有道理的。
更新 @paddy在注明t->dates[0] = someDateValue
的错误时是正确的
在这种情况下,所说的是:
char someDateValue[] = "2012-08-15";
在这种情况下,也可以写为
char *someDateValue = "2012-08-15";
这样
t->dates[0] = someDateValue;
只需指定字符串的指针,将指针替换为前面malloc
中新分配的块。
参考:如果您仍然感到困惑,可以阅读C FAQ问题6.3 So what is meant by the ``equivalence of pointers and arrays'' in C?以及C FAQ的其余部分。
建议str[n]cpy(或类似replacements)将数组内容(而非其指针)复制到新分配的内存块是正确的。