【问题标题】:Under what conditions may this function cause memory leakage?这个函数在什么情况下会导致内存泄漏?
【发布时间】:2020-10-26 11:23:24
【问题描述】:
char *expandspace (char* test) {
    static int i = 0;
    test  = realloc (test, ++i * 100); 
    if(test == NULL) {
        printf("realloc fail");
    }
    return test;
}

这个函数在什么情况下会导致内存泄漏?有没有办法修复它,让它工作 每次?谢谢。

【问题讨论】:

  • 这是一道作业题吗?

标签: c memory-leaks realloc


【解决方案1】:

如果realloc 失败,则不会释放原始内存块(例如,参见 cppreference.com 上的realloc):

如果没有足够的内存,旧的内存块不会被释放并且 返回空指针。

所以在这种情况下,您的函数将返回NULL。根据您是否将函数结果直接分配给传递给expandspace 的变量,在这种情况下您可能会发生泄漏:

有问题:

int main() {
   char* test = expandspace(NULL);  // let's assume this is OK...

   // possible leak: if realloc fails, test becomes NULL but the memory it pointed to did not get freed
   // and you lost the pointer, so you cannot free it any more:
   test = expandspace(test);    
}

更好:

int main() {
   char* test = expandspace(NULL);  // let's assume this is OK...

   char *newTest = expandspace(test);
   if (!newTest) {
      free(test);
      test=NULL;
   }
   ...
}

【讨论】:

  • 如果内存不足,您无能为力,只能优雅地关闭程序。发生这种情况时,内存泄漏是您最不关心的问题。这就像汽车发动机已经爆炸成碎片时担心汽车轮胎慢慢漏气一样。您需要问的问题是:什么可能导致 realloc 失败
  • @Lundin:也许,也许不是。未能为特定目的分配(可能很大)内存块并不一定意味着堆是“满的”;有(不总是但仍然)有意义的案例需要做出反应并“正常”地继续。
  • 另外,这可能意味着堆未满但已损坏 - 我可能会添加很可能的情况。在这种情况下,维护指向先前分配的数据的指针也可能没有意义,因为它也可能被破坏。无论堆是满还是损坏,你的执行环境都是烤面包,你需要终止。
  • @user253751:并非总是如此;如果test 在调用之前已经为 NULL,则不会。
【解决方案2】:

有一个常见但迂腐/人为的评论很多人喜欢做 - 它是:不要使用与 realloc 参数相同的指针并导致两者。因为万一 realloc 失败,你就丢失了指向原始内存的指针。

但是您需要问的问题是:是什么导致 realloc 无法开始?如果 realloc 失败,这意味着堆已满,您的程序无论如何都无法继续做任何有意义的事情 - 您将需要退出。所以这句话在实践中是无意义的——让你的程序在一个不存在可靠堆的未定义世界中运行是很危险的做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多