【问题标题】:Global variable and realloc and memory leak全局变量和重新分配以及内存泄漏
【发布时间】:2013-07-06 13:34:33
【问题描述】:

我想知道为什么valgrind 说:

    ==9952== 30 bytes in 6 blocks are definitely lost in loss record 1 of 1
    ==9952==    at 0x4C2BF0E: realloc (vg_replace_malloc.c:662)
    ==9952==    by 0x40131F: setCharsPositions (paramsExec.c:99)
    ==9952==    by 0x400CF3: main (main.c:87)

我无法弄清楚我的realloc() 有什么问题(您不必说每次重新分配内存效率低下...);变量char **passwordSet2 是全局的——也许这就是问题所在……如果我做错了什么,请告诉我!我要疯了!

void setCharsPositions(char *charsPos){

    int i, k;
    char *posStr = NULL;

    for(i = 0; i < strlen(charsPos); i++){

        posStr = malloc(sizeof(char));

        if(charsPos[i] == '['){

            for(k = 0, i++; charsPos[i] != ','; i++, k++){
                posStr[k] = charsPos[i];
                posStr = realloc(posStr, (k+2)*sizeof(char));
            }
            posStr[k] = '\0';

            passwordSet2[atoi(posStr)-1] = malloc(sizeof(char));
            for(k = 0, i++; charsPos[i] != ']'; i++, k++){
                passwordSet2[atoi(posStr)-1][k] = charsPos[i];
                passwordSet2[atoi(posStr)-1] = realloc(passwordSet2[atoi(posStr)-1], (k+2)*sizeof(char));
            }
            passwordSet2[atoi(posStr)-1][k] = '\0';
        }
        free(posStr);
    }
}

【问题讨论】:

  • sizeof (char) 始终为 1;你不必要地乘以 1。此外,一个最小的、可编译的测试用例会很好。考虑编写一个main 入口点以使其可编译。
  • 在很多地方不用atoi,你可以把它存储在像posInt这样的int变量中
  • @undefinedbehaviour 编译器不会优化乘以1吗?仅据我所知..
  • @VoidPointer 乘法不需要任何成本,只是毫无意义的混乱。
  • @VoidPointer 在这种情况下,优化运行时效率远不如优化人类可读性重要。

标签: c global-variables malloc valgrind realloc


【解决方案1】:
passwordSet2[atoi(posStr)-1] = malloc(sizeof(char));

如果之前分配了passwordSet2[atoi(posStr)-1],则会泄漏内存。也就是说,如果 posStr 的相同值出现不止一次,您就有泄漏。丢失的内存将来自以前的 realloc,这就是 valgrind 将报告的内容。 (如果您指出哪一个是第 662 行,这将有所帮助。)如果 posStr 的相同值不止一次出现但不应该出现,那么您需要检查这一点。如果允许多次发生,则应添加对free 的调用:

free(passwordSet2[atoi(posStr)-1]);
passwordSet2[atoi(posStr)-1] = malloc(sizeof(char));

free 的第一次出现,当 passwordSet2[atoi(posStr)-1] 为 NULL 时,是空操作。

此外,您没有检查 malloc 和 realloc 返回的 NULL,尽管这会导致您的程序崩溃,而不仅仅是泄漏。

最后,为了清晰和可能的效率,我强烈建议您将 atoi(posStr)-1 放入一个变量中,而不是重复它。

【讨论】:

  • FWIW,为了更好地完成这个答案,假设 realloc 返回NULL,这里也会有泄漏:posStr = realloc(posStr, (k+2)*sizeof(char));
  • 之前没有赋值,好吧,我这样初始化passwordSet2变量:for(i = 0; i
  • @undefinedbehaviour 在紧随其后的商店中还会有 UB,很可能是访问冲突,所以我认为这不会增加太多,因为问题不在于检查 NULL 返回。
  • @pcarrara 喜欢什么?无论如何,我不是在谈论初始化......请参阅我的补充话。
  • @JimBalter 是的,这是真的。我想realloc 的错误使用可以通过推荐访问"understanding realloc" 之类的问题来最快解决。
猜你喜欢
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
相关资源
最近更新 更多