我正在用C编写一个程序,它接受用户输入,当我输入Ctrl + d时,它会打印数千个(null)
作为输出。发生了什么事情?是某种内存泄漏吗?代码如下:
while (1) {
char *buffer = malloc(BUFFER_SIZE);
fgets(buffer, BUFFER_SIZE, stdin);
printf("%s", buffer);
}
BUFFER_SIZE
设置为 256。
是的,这可能是由于代码中的内存泄漏。您在循环的每个轮次中分配一些内存,但从不释放它。所以最终你会耗尽内存。
起初malloc
每次都会返回一个新的 256 字节内存块。fgets
从标准输入读取。由于用户按 Ctrl+D,因此标准输入为空,因此fgets
返回buffer
并且不写入任何内容。(fgets
不能保证写入空字符串,即在buffer[0]
处写入空字节,如果它没有读取任何内容。然后printf
打印buffer
的内容为1,这可能是任何随机垃圾,并且可能会崩溃,因为内存未初始化,并且不能保证有一个空字节来结束缓冲区中的字符串。合理地,如果这是你的程序唯一做的事情,操作系统为你的程序提供零填充内存,所以malloc
第一次使用特定的内存块时,它仍然填充零,所以buffer
是全字节零,这是一个空字符串,所以printf
调用没有可见的影响。
最终malloc
内存不足,因此它返回NULL
。使用空缓冲区调用fgets
通常会导致分段错误1。但是,在fgets
看到空输入的特殊情况下,它可能根本不会尝试访问缓冲区,因此它只返回NULL
。然后printf("%s", NULL)
,在您的平台1上打印(null)
.
解决方案是检查malloc
和fgets
的返回值,并释放您分配的内存。(当然,您可以分配一次缓冲区并重用它,而不是在每次迭代时分配一个新的缓冲区,但我假设这是一个学习练习或对更复杂问题的简化。
while (1) {
char *buffer = malloc(BUFFER_SIZE);
if (buffer == NULL) {
printf(stderr, "Out of memoryn");
exit(EXIT_FAILURE);
}
if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) break;
printf("%s", buffer);
free(buffer);
}
1一般来说,在 C 中,这具有未定义的行为。我正在描述平台上可能的行为,其中 Ctrl+D 是指示用户输入结束的标准键绑定。