strdup和内存泄漏 [英] strdup and memory leaking

查看:294
本文介绍了strdup和内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

strdup是否每次都分配另一个内存区域并创建另一个指针?

Does strdup allocate another memory zone and create another pointer every time?

例如:以下代码是否会导致内存泄漏?

For example: does the following code result in a memory leak?

void x(char** d, char* s){
    *d = strdup(s);
}

int main(){
    char* test = NULL;
    x(&test, "abcd");
    x(&test, "etc");
    return 0;
}

推荐答案

是的,该程序由于分配对象然后丢失对它们的引用而导致内存泄漏.

Yes, the program leaks memory because it allocates objects and then loses references to them.

第一次发生这种情况:

 x(&test, "etc");

变量test保存在上一次对x的调用中分配的指针的一个且唯一的副本.对x的新调用将覆盖该指针.此时,指针泄漏.

The variable test holds the one and only copy of a pointer that was allocated in a previous call to x. The new call to x overwrites that pointer. At that point, the pointer leaks.

这就是泄漏内存的含义:丢失对现有动态分配的存储的所有引用.

This is what it means to leak memory: to lose all references to an existing dynamically allocated piece of storage.

第二个泄漏发生在main函数返回时.此时,test变量被销毁,并且该变量保存指向"etc"字符串副本的指针的唯一且唯一的副本.

The second leak occurs when the main function returns. At that point, the test variable is destroyed, and that variable holds the one and only copy of a pointer to a duplicate of the "etc" string.

有时在C程序中,我们有时不关心第二种类型的泄漏:程序终止时不会释放的内存,但是不会在循环中一次又一次地分配内存(因此它不会导致失控)内存增长问题).

Sometimes in C programs, we sometimes not care about leaks of this second type: memory that is not freed when the program terminates, but that is not allocated over and over again in a loop (so it doesn't cause a runaway memory growth problem).

如果程序曾经集成到另一个程序(例如,作为共享库),其中原始的main函数成为可以在同一程序环境中重复调用的启动函数,则两个泄漏都将变成问题.

If the program is ever integrated into another program (for instance as a shared library) where the original main function becomes a startup function that could be invoked repeatedly in the same program environment, both the leaks will turn into problems.

POSIX strdup函数的行为与此类似:

The POSIX strdup function behaves similarly to this:

char *strdup(const char *orig)
{
   size_t bytes = strlen(orig) + 1;
   char *copy = malloc(bytes);
   if (copy != 0)
     memcpy(copy, orig, bytes);
   return copy;
}

是;每次分配新的存储空间.

Yes; it allocates new storage each time.

如果您的C映像中有一个垃圾收集器(例如Boehm),则泄漏的存储很有可能被回收,因此strdup能够将相同的内存重新用于第二次分配. (但是,除非在一个压力测试模式下运行以清除错误,否则垃圾收集器只分配一次就不会启动.)

If you have a garbage collector (such as Boehm) in your C image, then it's possible that the leaked storage is recycled, and so strdup is able to re-use the same memory for the second allocation. (However, a garbage collector is not going to kick in after just one allocation, unless it is operated in a stress-test mode for flushing out bugs.)

现在,如果您想通过realloc实际重用内存,则可以按照以下几行更改x函数:

Now if you want to actually reuse the memory with realloc, then you can change your x function along these lines:

#include <stdlib.h>
#include <string.h>

void *strealloc(char *origptr, char *strdata)
{
    size_t nbytes = strlen(strdata) + 1;
    char *newptr = (char *) realloc(origptr, nbytes); /* cast needed for C++ */
    if (newptr)
      memcpy(newptr, strdata, nbytes);
    return newptr;
}

(顺便说一下,以str开头的外部名称在ISO C保留的名称空间中,但是strealloc的名称太好了,不能拒绝.)

(By the way, external names starting with str are in an ISO C reserved namespace, but strealloc is too nice a name to refuse.)

请注意,界面不同.我们不传递指针到指针,而是提供类似realloc的接口.调用者可以检查返回值是否为null来检测分配错误,而在这种情况下,不必麻烦地用null覆盖指针.

Note that the interface is different. We do not pass in a pointer-to-pointer, but instead present a realloc-like interface. The caller can check the return value for null to detect an allocation error, without having the pointer inconveniently overwritten with null in that case.

main函数现在看起来像:

int main(void)
{
    char *test = strealloc(NULL, "abcd");
    test = strealloc(test, "etc");
    free(test);
    return 0;
}

像以前一样,没有错误检查.如果第一个strealloc失败,则test为null.那不是因为它仍然会被覆盖,并且strealloc的第一个参数可能为null.

Like before, there is no error checking. If the first strealloc were to fail, test is then null. That doesn't since it gets overwritten anyway, and the first argument of strealloc may be null.

只需一个free即可解决内存泄漏问题.

Only one free is needed to plug the memory leak.

这篇关于strdup和内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆