关于为与 fread 一起使用的 char* 分配内存的 C 问题

标签 c

所以我有这个代码

FILE* file = fopen("file.txt", "r");
if(file == NULL)
{
    printf("Failed to open file.\n");
    return NULL;
}

fseek(file, 0L, SEEK_END);
long bufferSize = ftell(file);
fseek(file, 0L, SEEK_SET);

char* buffer = (char*) malloc(bufferSize);
if(buffer == NULL)
{
    printf("Failed to allocate memory for buffer.\n");
    return NULL;
}

fread(buffer, sizeof(char), bufferSize, file);
fclose(file);

当使用 printf("%s", buffer) 打印到控制台时,这似乎工作得很好,但我想知道这是否会导致缓冲区溢出,或者是否错误,因为末尾似乎没有空终止符。 假设 file.txt 中正好有 4 个字符。当 bufferSize 计算出来时,它将是一个 long 值,值为 4。因此,当我调用 malloc(bufferSize) 时,我正在创建一个大小为 4 字节的缓冲区,占空值终结者字符。我到处都看到人们阅读整个文本文件的例子,他们使用这样的代码,但这不应该用文件中的字符创建一个 char* 而没有结束空终止符吗?我应该使用 malloc(bufferSize + 1) 分配此缓冲区并添加空终止符吗?

最佳答案

This seems to work perfectly fine when printing to console with printf("%s", buffer)

似乎工作得很好是 undefined behavior 的完美体现.

should i be allocating this buffer using malloc(bufferSize + 1) and adding a null terminator character?

如果您希望将 %s printf 格式说明符与指向可打印字符的连续字节的指针一起使用,则这些字节需要以零字节终止。或者相反,%s printf 格式说明符需要以零结尾的字节序列。否则,会发生未定义的行为。

所以:

  • 您的输入文件包含零字节,因此 %s 停止输出。
  • 您需要自己提供一个零终止字节,以确保 %s 知道在哪里停止。
  • 或者您可以自己迭代字节 for (...) { printf("%c", buffer[i]); } 或者(假设 bufferSize 低于 INT_MAX,所以可能是这样)只需通过指定精度来告诉 printf 何时停止格式说明符,例如:printf("%.*s", (int)bufferSize, buffer);

否则将会发生未定义的行为。

关于关于为与 fread 一起使用的 char* 分配内存的 C 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61003564/

相关文章:

c - #include "windows.h"它是如何工作的

c - 如何从函数内将指针(指向结构)设为 NULL

c++ - 如何删除 Grabcut 算法中不需要的空白?

c# - 用 C 编写的带有 Cocoa 前端的 OpenGL 游戏我想移植到 Windows

c - scanf 卡住了

条件比较

c - gdImageCopy 的图像是灰度的

c - 如何在C程序结束时自动打开.txt文件?

CTRL-C 处理程序无法正常工作

c - 为什么我得到以下输出 "**-858993460**"