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

C++ 类成员使用动态char数组时二进制读写程序异常问题

错误根因

你的代码核心问题是对包含指针成员的类直接进行内存二进制dump读写,不符合C++对象序列化规则:

  • Book类中的_title、_author是指针类型,sizeof(Book)统计的是指针本身的占用字节数,不会包含指针指向的堆内存中存储的字符串内容,你写入文件的只是程序运行时的临时内存地址,不是字符串本身。
  • 读取时你直接用文件内容覆盖了新Book对象的完整内存,把构造函数中正常分配的_title、_author指针替换为了文件中存储的无效旧地址,当该对象析构时,delete[]操作会访问非法内存,直接触发运行时崩溃。
  • 你之前使用定长char数组时功能正常,是因为定长数组的内存直接包含在类对象的内存空间中,整体dump时会把字符串内容一起写入文件,不存在指针引用外部内存的问题。

修复方案

不要直接读写整个类对象的内存,改为手动序列化每个成员:

  1. 写入时按顺序先写_titleLen、_authorLen、_year三个整数成员,再写_title、_author指向的字符串实际内容。
  2. 读取时对应先读三个整数成员,再根据长度分配内存读取字符串内容,避免覆盖指针本身的合法地址。

修正后代码

修正后的binaryFileWrite实现

void binaryFileWrite(const std::string &fileName = "binaryLibrary.bin")
{
    std::ofstream file(fileName, std::ios::binary);
    if (!file.is_open()) {
        std::cout << "Failed" << std::endl;
        exit(1);
    }
    // 写入整数成员
    file.write(reinterpret_cast<char*>(&_titleLen), sizeof(_titleLen));
    file.write(reinterpret_cast<char*>(&_authorLen), sizeof(_authorLen));
    file.write(reinterpret_cast<char*>(&_year), sizeof(_year));
    // 写入字符串实际内容
    file.write(_title, _titleLen);
    file.write(_author, _authorLen);
    file.close();
}

修正后的binaryFileRead实现

void binaryFileRead(const std::string& fileName = "binaryLibrary.bin")
{
    std::ifstream file(fileName, std::ios::binary);
    if (!file.is_open()) {
        std::cout << "Failed" << std::endl;
        exit(2);
    }
    // 释放原有内存避免泄漏
    delete[] _title;
    delete[] _author;
    // 读取整数成员
    file.read(reinterpret_cast<char*>(&_titleLen), sizeof(_titleLen));
    file.read(reinterpret_cast<char*>(&_authorLen), sizeof(_authorLen));
    file.read(reinterpret_cast<char*>(&_year), sizeof(_year));
    // 按读取的长度分配内存,读取字符串
    _title = new char[_titleLen + 1];
    _author = new char[_authorLen + 1];
    file.read(_title, _titleLen);
    file.read(_author, _authorLen);
    // 补字符串结束符
    _title[_titleLen] = '\0';
    _author[_authorLen] = '\0';
    // 输出内容
    std::cout << _title << " " << _author << " " << _year << std::endl;
    file.close();
}

额外注意事项

  • 你当前的代码每次调用binaryFileWrite都会覆盖原有文件内容,book2写入后会覆盖book1的内容,如果需要存储多本图书数据,写入时要添加std::ios::app追加模式,读取时也要对应循环读取。
  • 你的Book类当前没有实现拷贝赋值运算符,存在浅拷贝风险,建议补充实现,避免后续其他场景出现内存问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:18:02