找不到内存泄漏。凝视1小时

时间:2015-02-11 11:07:54

标签: c pointers memory memory-leaks valgrind

以下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);
}   

3 个答案:

答案 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*,因为它就是
  • 没有混淆(和不可见)typedef
  • 只有在您知道您确实需要新节点时才会调用
  • malloc()
  • 删除了由未使用指针构造指针
  • 引起的过多变量和条件
  • 使用strdup(),因为这更简单

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;
}