以下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] );
Valgrind的:
==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);
}
答案 0 :(得分:4)
释放节点,但不释放数据。
while ( startPtr != NULL ){
LISTNODEPTR tmp = startPtr;
startPtr = startPtr->nextPtr;
free(tmp->data); // Line added
free(tmp);
}
答案 1 :(得分:3)
存在内存泄漏,因为您在函数本地分配的指针永远不能从函数外部访问。
malloc(sizeof(SIZE))
也是错误的,您应该将其更改为malloc(SIZE)
,如果它是固定值,您应该合理地将data
成员声明为char data[SIZE]
而不是malloc()
空间。
简短回答
内存泄漏是由于您的程序没有free()
malloc()
内存。
答案 2 :(得分:2)
简化为:
value[SIZE]
参数更改为char*
,因为它就是struct listnode {
struct listnode *nextPtr;
char *data;
};
void insert ( struct listnode **pp, char *value ) {
struct listnode *newPtr;
int cmp;
/* find place to insert in LL */
while ( *pp) {
/* Comparision to detect & remove duplicates nodes */
cmp = strcmp(value, (*pp)->data);
/* Duplicate: nothing to do ... */
if (cmp == 0) return;
/* you're at the point where you need to add the node */
if (cmp < 0) break;
pp = &(*pp)->nextPtr;
}
/* when you get here, *pp points to the pointer you want to change.
** *pp could even be NULL (if we are at the end of the list)
*/
newPtr = malloc(sizeof *newPtr);
if ( !newPtr ) { barf(); return; }
newPtr->data = strdup (value);
/* you could check newPtr->data here, and if null: free(newPtr) */
/* "steal" the pointer */
newPtr->nextPtr = *pp;
/* and inject the new pointer into the LL */
*pp = newPtr;
return;
}