以下 C 代码中的内存泄漏

发布于 2024-12-04 10:53:25 字数 1952 浏览 1 评论 0原文

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

            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== 

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

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== 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泅人 2024-12-11 10:53:25

您的代码实际上应该更像这样:

#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() 中释放数据结构。

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.

莳間冲淡了誓言ζ 2024-12-11 10:53:25

只需在不再需要时释放已使用的内存即可:

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

顺便说一句:当这是整个程序时,实际上并不重要。由于操作系统在进程结束时回收所有未释放的内存,因此不需要释放直到程序终止为止正在使用的内存。然而,这是一个很好的做法。

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.

一世旳自豪 2024-12-11 10:53:25

现在阅读了评论中的更新后,分配和返回内存的模块(称为 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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文