You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用字符串实现fread()和fwrite()时遇崩溃及读取失败问题求助

问题分析与解决方法

核心错误原因

你的代码存在两个致命问题,直接触发内存错误:

  1. 错误读写std::string对象本身:
    std::string是包含内部指针、长度、容量的复合对象,sizeof(value)获取的是该对象的内存大小(通常12或24字节,取决于平台),而非字符串内容的长度。你写入文件的是string的内部结构(比如指向堆内存的指针),而非"abcd"本身;读取时直接覆盖retrieved对象的内存,会破坏其内部指针,析构时触发free(): invalid pointer或段错误。
  2. 空string越界访问:
    当retrieved是空字符串时,retrieved[0]属于未定义行为——空string没有可访问的字符元素,无法通过这种方式写入数据。

正确实现方式

要正确读写std::string的内容,需要先写入字符串的长度(或写入带终止符的内容),再写入实际字符;读取时先获取长度,再分配足够空间读取内容。以下是可靠的实现:

修正后的代码

#include <cstdio>
#include <string>
#include <iostream>

static bool file_read(FILE* file) {
    std::string value = "abcd";
    std::string retrieved;

    // 写入字符串:先写长度,再写内容
    const size_t len = value.size();
    fwrite(&len, sizeof(len), 1, file);
    fwrite(value.data(), sizeof(char), len, file);

    // 回到文件开头
    fseek(file, 0, SEEK_SET);

    // 读取字符串:先读长度,再分配空间读内容
    size_t read_len;
    fread(&read_len, sizeof(read_len), 1, file);
    retrieved.resize(read_len); // 为读取内容分配足够空间
    fread(retrieved.data(), sizeof(char), read_len, file);

    // 验证结果
    std::cout << "读取到的字符串:" << retrieved << std::endl;
    return true;
}

int main(int argc, char *argv[]) {
    FILE *file = fopen("file_test", "wb+");
    if (!file) {
        std::cerr << "文件打开失败" << std::endl;
        return 1;
    }
    file_read(file);
    fclose(file);
    return 0;
}

关键步骤说明

  • 写入逻辑:
    1. 先写入字符串的长度,确保读取时知道需要分配多少内存。
    2. 使用value.data()获取字符串内容的指针,写入实际的字符数据(value.c_str()也可,但data()更适合写入操作)。
  • 读取逻辑:
    1. 先读取之前写入的长度值。
    2. 调用retrieved.resize(read_len)为字符串分配足够的内存空间。
    3. 读取字符数据到retrieved.data()指向的内存区域。

可选方案:写入带终止符的字符串

如果你的字符串不包含\0字符,也可以写入带终止符的内容,读取时直接转为string:

// 写入
fwrite(value.c_str(), sizeof(char), value.size() + 1, file);

// 读取
char buffer[1024];
fread(buffer, sizeof(char), sizeof(buffer), file);
retrieved = buffer;

这种方式更简单,但无法处理包含\0的字符串,可靠性不如长度前缀的方式。

内容的提问来源于stack exchange,提问作者Yunho Jin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:05:31