来自 C++ 的 fread 示例 参考
我在编写 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;
}
在我看来,如果 result != lSize,那么 free(buffer) 将永远不会被调用。 在这个例子中这会是内存泄漏吗?
我一直认为他们网站上的示例质量非常高。 也许我理解不正确?
I often use the website www.cplusplus.com as a reference when writing C code.
I was reading the example cited on the page for fread and had a question.
As an example they post:
/* 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;
}
It seems to me that that if result != lSize, then free(buffer) will never get called. Would this be a memory leak in this example?
I have always thought the examples on their site are of a very high quality. Perhaps I am not understanding correctly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在这个示例中,这不会是内存泄漏,因为终止程序(通过调用
exit()
)会释放与其关联的所有内存。但是,如果您将这段代码用作子例程并调用类似
return 1;
的内容来代替exit()
,则会出现内存泄漏。It wouldn't be a memory leak in this example, because terminating the program (by calling
exit()
) frees all memory associated with it.However, it would be a memory leak if you used this piece of code as a subroutine and called something like
return 1;
in place ofexit()
.从技术上讲,是的,这是内存泄漏。 但是,当进程终止时,进程分配的任何内存都会自动释放,因此在本例中,实际上并不需要调用 free(和 fclose)。
在更复杂的程序中,这可能是一个真正的问题。 缺少 free 会导致内存泄漏,缺少 fclose 会导致资源泄漏。
Technically, yes it is a memory leak. But any memory allocated by a process is automatically freed when that process terminates, so in this example the calls to free (and fclose) are not really required.
In a more complex program, this would probably be a real problem. The missing free would create a memory leak and the missing fclose would cause a resource leak.
当进程关闭时,操作系统会清理该进程所有未释放的内存。 至少,现代操作系统是这样的。
The operating system cleans up any unfreed memory by a process when that process closes. At least, modern operating systems do.
如果程序没有在 result != lSize 处退出,也就是说,它继续执行其他一些路径,那么是的 - 这肯定是内存泄漏。
If the program were not exiting at the point result != lSize, that is, it continued with some other path of execution, then yes - it is a guaranteed memory leak.
有两条可能的路径。
(1) result != lSize - 在这种情况下,调用 exit(0)。 这会杀死进程,操作系统将清理内存。
(2) result == lsize - 在这种情况下,缓冲区被显式释放,但随后立即调用 return,因此释放大多只是良好的风格,因为这也会杀死进程,并且操作系统将再次清理内存。
所以在这个简单的情况下,不存在内存泄漏。 但确保释放在您编写的任何应用程序中分配的所有内存可能是一个很好的做法。 养成这个习惯可以避免你将来遇到很多麻烦。
There are two possible paths.
(1) result != lSize - in this case, exit(0) is called. This kills the process and the operating system will clean up the memory.
(2) result == lsize - in this case, the buffer is explicitly freed, but return is called right afterwards so the free is mostly just good style because this also kills the process and the operating system will, again, clean up the memory.
So in this simple case, there is no memory leak. But it is probably a good practice to just make sure you're freeing any memory you've allocated in any application you write. Getting into this habit will prevent many headaches for you in the future.
至于可能的内存泄漏,其他人已经回答了这个问题。 不久前,我发布了给定代码的变体,它应该正确处理所有可能的错误情况:
As to possible memory leakage, other's have already answered that question. A while ago, I posted a variation of the given code which should handle all possible error conditions correctly: