【问题标题】:Memory leak with malloc and fgetcmalloc 和 fgetc 的内存泄漏
【发布时间】:2017-08-29 20:41:32
【问题描述】:

我在使用 malloc 和 getchar 读取用户的赞时遇到了一些问题。我得到了结果,但是,我使用 valgrind 得到了内存泄漏。我对此一无所知,并询问了我的同学和导师,但似乎没有人知道原因。

char *ReadLineFile(FILE *infile){
   int i=0;
   char c;
   char *newStringLine;
   newStringLine = (char *) malloc(sizeof(char));
   while( (c = fgetc(infile)) != '\n' ){
        newStringLine[i++] = c;
        realloc(newStringLine, (sizeof(char) * (i+1)));
   }
   newStringLine[i] = '\0';
   return newStringLine;
}

Valgrind 给了我几个错误,包括 Invalid write/read of 1 和 invalid realloc。

【问题讨论】:

标签: c pointers dynamic-memory-allocation realloc


【解决方案1】:

您对realloc() 的使用是错误的。

realloc(),如果成功,则释放传递的指针并返回一个带有分配内存的新指针。你需要

  • 在一个临时指针中捕捉realloc()的返回值,
  • 检查 NULL 以确保成功,然后

    • 如果返回的指针不为NULL,即重新分配成功,使用新的指针。
    • 如果返回的指针为 NULL,请做出一些决定,您可以继续使用旧指针(作为参数传递)。

相关,引用 C11,第 7.22.3.5 章

realloc 函数释放ptr 指向的旧对象 并返回一个 指向具有size 指定大小的新对象。 [....]

和,

[...] 如果新对象的内存不能 已分配,旧对象不会被释放,其值不变。

否则,如果realloc() 成功,您(很可能)试图使用已经空闲的内存,这当然会导致undefined behavior


呃-哦,我提到了吗,please see this discussion on why not to cast the return value of malloc() and family in C

【讨论】:

  • " 如果 realloc() 成功,您正在尝试使用已经释放的内存":不一定,如果系统只是增加块的大小而不移动内存(这经常发生)。但这是轮盘赌。
  • @Jean-FrançoisFabre 好吧,这不能保证,对吧?更好地发挥安全。 :)
  • 当然!但我见过这样的其他问题,OP 可以将他的代码运行到内存移动的某个点。错误的印象,它正在工作!
  • @Jean-FrançoisFabre 先生,这正是我想要避免的。不过添加了注释。 :)
  • 成功了!正如建议的那样,我使用了一个临时变量,然后简单地将它分配回我的 newStringLine 指针。这绝对给我上了一课!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
相关资源
最近更新 更多