以下C代码中的内存泄漏

时间:2011-09-13 10:21:54

标签: c memory-management memory-leaks valgrind

对于以下代码示例,存在内存泄漏。在下列情况下,我们如何防止内存泄漏:

            1 #include <stdio.h>
            2 #include <stdlib.h>
            3 
            4 typedef struct sample_help {
            5 int *value;
            6 void **pointers;
            7 }*sample,sample_node;
            8 
            9 
            10 sample main(){
            11 sample  ABC=NULL; 
            12 sample  XYZ=NULL;
            13 sample  kanchi = NULL;
            14 
            15 ABC = malloc(sizeof(sample_node));
            16 XYZ = malloc(sizeof(sample_node));
            17 ABC->pointers = malloc(5*sizeof(void *));
            18 XYZ->pointers = malloc(5*sizeof(void *));
            19 ABC->value = malloc(5*sizeof(int));
            20 XYZ->value = malloc(5*sizeof(int));
            21 
            22 ABC->value[0] = 10;
            23 ABC->value[1] = 20;
            24 
            25 XYZ->pointers[0] = ABC;
            26 kanchi = XYZ->pointers[0];
            27 
            28 printf("::::%d\n",XYZ->pointers[0]);
            29 printf("kanchi1:::::%d\n",kanchi->value[0]);
            30 
            31 
            32 return XYZ;
            33 }
            34 

以下是valgrind的输出。

==27448== 
==27448== HEAP SUMMARY:
==27448==     in use at exit: 152 bytes in 6 blocks 
==27448==   total heap usage: 6 allocs, 0 frees, 152 bytes allocated
==27448== 
==27448== 152 (16 direct, 136 indirect) bytes in 1 blocks are definitely lost in loss  record 6 of 6
==27448==    at 0x4C244E8: malloc (vg_replace_malloc.c:236)
==27448==    by 0x40056B: main (test2.c:16)
==27448== 
==27448== LEAK SUMMARY:
==27448==    definitely lost: 16 bytes in 1 blocks
==27448==    indirectly lost: 136 bytes in 5 blocks
==27448==      possibly lost: 0 bytes in 0 blocks
==27448==    still reachable: 0 bytes in 0 blocks
==27448==         suppressed: 0 bytes in 0 blocks  
==27448== 

3 个答案:

答案 0 :(得分:3)

您的代码应该更像这样:

#include <stdio.h>
#include <stdlib.h>

typedef struct sample_help {
    int *value;
    void **pointers;
} *sample, sample_node;

sample foo(void)
{
    sample  ABC=NULL;
    sample  XYZ=NULL;
    sample  kanchi = NULL;

    ABC = malloc(sizeof(sample_node));
    XYZ = malloc(sizeof(sample_node));
    ABC->pointers = malloc(5*sizeof(void *));
    XYZ->pointers = malloc(5*sizeof(void *));
    ABC->value = malloc(5*sizeof(int));
    XYZ->value = malloc(5*sizeof(int));

    ABC->value[0] = 10;
    ABC->value[1] = 20;

    XYZ->pointers[0] = ABC;
    kanchi = XYZ->pointers[0];

    printf("::::%d\n",XYZ->pointers[0]);
    printf("kanchi1:::::%d\n",kanchi->value[0]);

    return XYZ;
}

int main(void)
{
    // call your function
    sample xyz = foo();

    // ... do something with the data structure xyz ...

    // free memory allocated by your function
    free(xyz->pointers[0]->value);    // free ABC->value
    free(xyz->pointers[0]->pointers); // free ABC->pointers
    free(xyz->pointers[0]);           // free ABC
    free(xyz->value);                 // free XYZ->value
    free(xyz->pointers);              // free XYZ->pointers
    free(xyz);                        // free XYZ

    return 0;
}

请注意,在完成后,我们从main()中释放数据结构。

答案 1 :(得分:2)

在不再需要时释放已用内存:

free(ABC->value);
free(XYZ->value);
free(ABC->pointers);
free(XYZ->pointers);
free(ABC);
free(XYZ);
顺便说一下:当这是整个程序时,它实际上并不重要。由于OS在进程结束时回收所有未使用的内存,因此不需要释放在程序终止之前使用的内存。但是,这是一种很好的做法。

答案 2 :(得分:2)

现在已经在评论中阅读了您的更新,您的模块(称为main())分配并返回内存就可以了。

无论模块使用模块返回的值,都需要在使用后释放数据。因此,如果您将模块实现为

sample mymodule(void)
{
    sample foo = malloc(10);
    /* set up contents of foo as required */
    return foo;
}

然后mymodule的调用者会这样:

int main (int argc, char *argv[])
{
    sample bar = mymodule();
    /* use contents of bar as required */
    free(bar);
    return 0;
}