繁体   English   中英

无论如何,是否要检查C中是否存在内存泄漏?

[英]Is there anyway to check if there is memory leaks in C?

我最近了解了memalloc()和free(),我只是想知道是否有一种方法可以适当地检查是否所有的memallocs是否都被适当地释放了?

我在这里有这段代码用于实现双链表,并且不清楚id是否需要遍历每个节点并释放每个p1和p2,还是只算一次?

struct s {
    int data;
    struct s *p1;
    struct s *p2;
};

void freedl(struct s *p)
{
    if(p->p1 != NULL)
    {
        printf("free %d \n", p->p1->data);
    }

    if(p->p2 != NULL)
    {
        freedl(p->p2);
    }
    else
    {
        printf("free last %d", p->data);
        free(p);
    }

}

int main(void) {

    struct s *one, *two, *three, *four, *five, *six;

    one = malloc(sizeof *one);
    two = malloc(sizeof *two);
    three = malloc(sizeof *three);
    four = malloc(sizeof *four);
    five = malloc(sizeof *five);
    six = malloc(sizeof *six);

    one->data = 1;
    one->p1 = NULL;
    one->p2 = two;

    two->data = 2;
    two->p1 = one;
    two->p2 = three;

    three->data = 3;
    three->p1 = two;
    three->p2 = four;

    four->data = 4;
    four->p1 = three;
    four->p2 = five;

    five->data = 5;
    five->p1 = four;
    five->p2 = six;

    six->data = 6;
    six->p1 = five;
    six->p2 = NULL;

    freedl(one);

    return EXIT_SUCCESS;
}

我只想确保我做得对!

答案是“是”。 到底有多难,取决于您所使用的操作系统。

如果您使用的是Linux,Mac OS X或BSD之一(FreeBSD,OpenBSD等):

(可能还有Hai句)

您可以使用一个名为valgrind的实用程序。 这是一个出色的实用程序,其目的是(尤其是)检查内存泄漏。

基本用法很简单:

valgrind ./my-program

虽然它是一个复杂的实用程序,所以我建议您查阅valgrind手册以了解更多高级用法。

实际上,它的作用远不止于此,因为它可以检测到许多(但不是全部)越界访问和类似问题。 它还包括其他可能有用的工具,例如用于分析代码的callgrind

但是请注意,由于运行方式, valgrind将使程序运行非常缓慢。

任何其他操作系统(包括Windows):

不幸的是,没有适用于Windows的实用程序(无论如何,没有免费的实用程序;而商用的实用程序却花了一笔不小的钱,最后我检查过---并没有valgrind和朋友能做的那么多)。

但是,您可以执行宏并在退出时手动检查:

#define malloc(size) chk_malloc(size, __FILE__, __LINE__)
#define free(ptr)    chk_free(ptr, __FILE__, __LINE__)
// etc... for realloc, calloc

...

// at start of main():
atexit(chk_report); // report problems when program exits normally

然后,您必须实现chk_mallocchk_free等。 但是,如果您执行诸如setAllocator(malloc)类的操作,可能会有一些“泄漏”。 如果您可以接受丢失线路信息的信息,则可以尝试执行以下操作:

#define malloc chk_malloc // chk_malloc now only takes 1 argument
#define free   chk_free
...

有一些黑客这将让你保持文件/行信息即使有这样#define ,但他们的问题严重复杂化(这将涉及基本封黑客进入C)。

如果您不希望以任何方式更改代码,则可以尝试替换那些函数(通过用自己的填充DLL替换stdlib)来试试运气,尽管您不会以这种方式获取文件/行信息。 如果编译是静态完成的,或者编译器已将其替换为某些内在函数(对于malloc来说不太可能,但并非不可想象),这也可能会带来问题。

实现可以很简单,也可以很复杂,具体取决于您。 我不知道任何现有的实现,但是您可能可以在网上找到一些东西。

系统分配器可以通过某种方式获取统计信息(例如分配的字节)。 (在Linux上为mallinfo )。 在程序的开始,您应该存储分配的字节数,最后不需要确保数目相同。 如果数字不同,则可能存在内存泄漏。

发现泄漏是另一回事。 valgrind之类的工具会有所帮助。

您可以使用valgrind但速度可能会有些慢,或者在编译器中有内置功能。 例如在clang (我也认为在gcc 4.9中)有LeakSanitizer

$ cat example.c
int main()
{
    malloc(100);
    return 0;
}

$ clang -fsanitize=leak -g example.c -fsanitize=address
$ ASAN_OPTIONS=detect_leaks=1  ./a.out

=================================================================
==9038==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 100 byte(s) in 1 object(s) allocated from:
    #0 0x46c871 (/home/debian/a.out+0x46c871)
    #1 0x49888c (/home/debian/a.out+0x49888c)
    #2 0x7fea542e4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)

SUMMARY: AddressSanitizer: 100 byte(s) leaked in 1 allocation(s).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM