【问题标题】:Read file contents with unknown size读取未知大小的文件内容
【发布时间】:2011-05-08 04:15:07
【问题描述】:

我想处理配置文件的内容。配置文件可以是任意大小。程序挂起后,当我运行以下代码时,出现总线错误:

FILE *fp;
struct stat st;
char *buffer;

fp = fopen(CONFIG_FILE, "r");
if (fp == NULL) {
    // error handling and cleanup omitted for brevity
}

fstat(fileno(fp), &st);
fread(buffer, sizeof(char), st.st_size, fp);
fprintf(stderr, "%s\n", *buffer);
fclose(fp);

我了解到总线错误可能是由缓冲区溢出引起的。我很确定我的char *buffer 出现缓冲区溢出。但是,如何在运行时指定缓冲区的大小?

编辑 - 总线错误是由于我懒于在 fread 调用中硬编码 1 造成的。代码示例已更新以解决此问题,改为使用 sizeof(char)

【问题讨论】:

  • sizeof(char) == 1 是有保证的。
  • @Alok,我就是这么想的,但是当我有 1 时它崩溃了......哦,好吧,无论如何硬编码都很糟糕
  • C 标准保证sizeof(char) 为1。所以在这种情况下硬编码是可以的。

标签: c stdio


【解决方案1】:

使用malloc(3)。放:

buffer = malloc(st.st_size);

在您致电fread() 之前。完成后不要忘记释放buffer

您可能也不想在您的printf() 通话中使用*buffer。如果您要尝试像这样打印整个文件,则需要确保分配一个额外的字节来以空值终止您的字符串。

【讨论】:

  • @Carl,当我 malloc(st.st_size + 1) 时,是否将最后一个元素显式设置为 \0
  • @Mad Rapper X - 应该可以,是的。 @muntoo,你在问什么?
【解决方案2】:

你可以用malloc分配内存:

buffer = malloc(number_of_bytes_to_allocate);
if(buffer == NULL) {
    // error allocating memory
}

free 完成后!

free(buffer);

【讨论】:

    【解决方案3】:

    在 C99 中,假设您的配置文件不应在 MiB 或更大范围内,您可以使用 VLA:

    FILE *fp = fopen(CONFIG_FILE, "r");
    if (fp == NULL) {
        // error handling and cleanup omitted for brevity
    }
    
    struct stat st;
    fstat(fileno(fp), &st);  // Error check omitted
    char buffer[st.st_size+1];
    fread(buffer, sizeof(char), st.st_size, fp);
    buffer[st.st_size] = '\0';
    fprintf(stderr, "%s\n", *buffer);
    fclose(fp);
    

    【讨论】:

    • 警告.. 有人可能会不小心或恶意故意给你一个二进制文件。那么'%s'是什么。永远不要假设输入是你所期望的!
    猜你喜欢
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多