Утечка памяти в следующем коде C - PullRequest
1 голос
/ 13 сентября 2011

Для следующего примера кода есть утечка памяти.Как мы можем предотвратить утечку памяти в следующем случае:

            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 ]

3 голосов
/ 13 сентября 2011

Ваш код действительно должен быть примерно таким:

#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 () после того, как с ней закончим.

2 голосов
/ 13 сентября 2011

Теперь прочитав ваше обновление в комментариях, ваш модуль (, а не , называемый 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;
}
2 голосов
/ 13 сентября 2011

Просто освободите использованную память, когда она больше не нужна:

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

Кстати: когда это целая программа, это на самом деле не имеет значения.Поскольку операционная система освобождает всю неосвобожденную память после завершения процесса, память, которая используется до завершения программы, освобождать не требуется.Однако это хорошая практика.

...