开发者

Memory leak in the following C code

开发者 https://www.devze.com 2023-04-05 00:39 出处:网络
For the following sample of code there is memory leak. How can we prevent memory leak in the following case:

For the following sample of code there is memory leak. How can we prevent memory leak in the following case:

            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->point开发者_如何学JAVAers[0];
            27 
            28 printf("::::%d\n",XYZ->pointers[0]);
            29 printf("kanchi1:::::%d\n",kanchi->value[0]);
            30 
            31 
            32 return XYZ;
            33 }
            34 

Following is the output of 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== 


Your code should really be more like this:

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

Note that we free the data structure from within main() after we're done with it.


Just free the used memory when it's no longer needed:

free(ABC->value);
free(XYZ->value);
free(ABC->pointers);
free(XYZ->pointers);
free(ABC);
free(XYZ);

Btw: When this is the whole program, it wouldn't actually matter. Since the OS reclaims all unfreed memory when a process is ended, memory that is in use until the termination of the programm is not required to be freed. However, it is good practice.


Having now read your update in the comments, your module (not called main()) that allocates and returns the memory is fine.

Whatever module uses the value returned from your module, needs to free the data after use. So if you implement your module as

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

Then the caller of mymodule would go like this:

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

精彩评论

暂无评论...
验证码 换一张
取 消