【发布时间】:2015-04-11 17:35:29
【问题描述】:
以下 C 代码存在内存泄漏。我盯着它看了一个小时,但找不到它。我已经能够将其缩小到该功能,但仍然没有改进的运气。
你能帮我找到吗?
感谢任何帮助。谢谢!
void insert ( LISTNODEPTR *sPtr, char value[SIZE] ) {
LISTNODEPTR newPtr, previousPtr, currentPtr;
int cmp;
newPtr = malloc(sizeof(LISTNODE));
if ( newPtr != NULL ) {
newPtr->data = malloc(sizeof(SIZE));
strcpy(newPtr->data, value);
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *sPtr;
/* Comparision to detect & remove duplicates nodes */
while ( currentPtr != NULL ) {
cmp = strcmp(value, currentPtr->data);
if (cmp < 0) {
/* you're at the point where you need to add the node */
break;
} else if (cmp == 0) {
/* value is equal, no duplicate is allowed, leave */
// since it is not added, destroy!
free(newPtr->data);
free(newPtr);
return;
}
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if ( previousPtr == NULL ) {
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
}
编辑:
更多代码:
#define SIZE 1001
struct listNode {
char *data;
struct listNode *nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;
/* Function prototype */
void insert ( LISTNODEPTR *, char[SIZE] );
瓦尔格林:
==19906== LEAK SUMMARY:
==19906== definitely lost: 12 bytes in 3 blocks
==19906== indirectly lost: 0 bytes in 0 blocks
==19906== possibly lost: 0 bytes in 0 blocks
==19906== still reachable: 0 bytes in 0 blocks
==19906== suppressed: 0 bytes in 0 blocks
如果我将 sizeof(SIZE) 转换为 SIZE,那么内存泄漏将变为 +3000。
编辑 2:
我确实在 main() 中释放它们
while ( startPtr != NULL ){
LISTNODEPTR tmp = startPtr;
startPtr = startPtr->nextPtr;
free(tmp);
}
【问题讨论】:
-
你怎么知道有内存泄漏?和
malloc(sizeof(SIZE));你确定吗? -
这里的
SIZE是什么?newPtr->data = malloc(sizeof(SIZE)); -
很确定应该是
malloc(SIZE)。如果它是一个宏,你当前的malloc(sizeof(SIZE))将 malloc 的大小为int(我没有理由认为它不是)。因此,除非您要复制的字符串在 32 位int实现上是 3 个字符长或更短,否则您将使用该strcpy调用未定义的行为。 -
顺便说一句,使用 Valgrind 的道具。
-
我不在乎尺寸损失的增加。之前的代码完全错误,需要修复。您的实际泄漏是由于您未能在 free 中的节点指针之前释放数据块。最后,您在执行此操作时不需要所有额外的指针杂耍。传递给您的函数的指针对指针几乎可以轻松完成所有这些工作。 see example.
标签: c pointers memory memory-leaks valgrind