c语言 - 输入中的 Ctrl-D 打印数千个空字符



我正在用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).

解决方案是检查mallocfgets的返回值,并释放您分配的内存。(当然,您可以分配一次缓冲区并重用它,而不是在每次迭代时分配一个新的缓冲区,但我假设这是一个学习练习或对更复杂问题的简化。

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 是指示用户输入结束的标准键绑定。

最新更新