2

在编写 C 代码时,我经常使用网站 www.cplusplus.com 作为参考。

我正在阅读页面上引用的示例以获取fread并且有一个问题。

作为一个例子,他们发布:

/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>

int main () {
  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;

  pFile = fopen ( "myfile.bin" , "rb" );
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

  /* the whole file is now loaded in the memory buffer. */

  // terminate
  fclose (pFile);
  free (buffer);
  return 0;
}

在我看来,如果结果!= lSize,那么 free(buffer) 将永远不会被调用。在这个例子中这会是内存泄漏吗?

我一直认为他们网站上的示例质量很高。也许我没有正确理解?

4

6 回答 6

4

从技术上讲,是的,这是内存泄漏。但是当进程终止时,进程分配的任何内存都会自动释放,所以在这个例子中,对 free(和 fclose)的调用并不是真正需要的。

在更复杂的程序中,这可能是一个真正的问题。丢失的 free 会造成内存泄漏,而丢失的 fclose 会导致资源泄漏。

于 2009-01-29T22:05:37.503 回答
4

在这个例子中它不会是内存泄漏,因为终止程序(通过调用exit())会释放与其相关的所有内存。

但是,如果您将这段代码用作子例程并调用类似的东西return 1;来代替exit().

于 2009-01-29T22:06:34.507 回答
0

当进程关闭时,操作系统会清除该进程的所有未释放内存。至少,现代操作系统可以。

于 2009-01-29T22:04:01.237 回答
0

如果程序没有在 result != lSize 处退出,也就是说,它继续执行其他一些路径,那么是的 - 这是有保证的内存泄漏。

于 2009-01-29T22:05:13.573 回答
0

有两种可能的路径。

(1) result != lSize - 在这种情况下,exit(0) 被调用。这会杀死进程,操作系统将清理内存。

(2) result == lsize - 在这种情况下,缓冲区是显式释放的,但之后会立即调用 return,因此 free 主要是一种很好的风格,因为这也会杀死进程,并且操作系统将再次清理内存.

所以在这个简单的情况下,没有内存泄漏。但是,确保释放在您编写的任何应用程序中分配的任何内存可能是一个好习惯。养成这个习惯可以防止你以后遇到很多麻烦。

于 2009-01-29T22:11:51.987 回答
0

至于可能的内存泄漏,其他人已经回答了这个问题。不久前,我发布了一个给定代码的变体,它应该正确处理所有可能的错误情况:

于 2009-01-29T22:22:08.487 回答