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

C++读写二进制存储的struct时出现Access violation异常如何解决?

问题根因

你遇到的访问违规错误核心是不能直接对包含std::string的结构体执行二进制读写操作:

  • std::string不属于POD(简单旧数据)类型,内部存储的是指向堆内存的字符串指针、长度、容量等元数据,你调用write写入文件的只是这些元数据(包括当时进程空间内的内存地址),并没有写入字符串的实际内容。
  • 读取时你把读到的无效地址直接赋值给新的std::string对象,访问这个非法地址时就会触发内存访问违规。
    同时sizeof(review)得到的只是两个std::string对象的固定占用大小,和字符串实际长度无关,你的偏移寻址逻辑本身也完全不生效。

解决方案

方案1:改用固定长度字符数组(适合需要随机访问的场景)

将结构体替换为固定长度的字符数组,使其成为POD类型,即可直接按固定偏移做二进制读写:

#include <iostream>    
#include <fstream>  
#include <cstring>   
using namespace std;

struct review {
    char text[256]; // 按最大可能的字符串长度设置固定大小
    char date[64];
};

void getRegistry(int i) {
    review reg; // 无需动态申请,栈上分配即可
    ifstream file("test.txt", ios::binary);
    if (file) {
        file.seekg(i * sizeof(review), ios::beg);
        file.read(reinterpret_cast<char*>(&reg), sizeof(review));
        cout << reg.text << endl;
        file.close();
    }
}

void generateBinary()
{
    ofstream arq("test.txt", ios::binary);
    review x;
    // 用字符串拷贝给字符数组赋值
    strncpy(x.text, "asdasdasd", sizeof(x.text)-1);
    strncpy(x.date, "qweqweqwe", sizeof(x.date)-1);
    for (int i = 1; i <= 1000000; i++)
    {
        arq.write(reinterpret_cast<const char*>(&x), sizeof(review));
    }
    arq.close();
}

int main() {
    generateBinary();
    getRegistry(2);
    return 0;
}

方案2:自定义序列化逻辑(适合动态长度字符串场景)

如果需要保留动态长度的std::string,需要自行实现序列化逻辑,先写入字符串长度再写入字符串内容:

注意:该方案下每条记录长度不固定,无法直接按固定偏移做随机访问,若需要随机访问需额外建立索引表存储每条记录的起始偏移。

// 写单条review逻辑
void writeReview(ofstream& os, const review& r) {
    size_t text_len = r.text.size();
    os.write(reinterpret_cast<const char*>(&text_len), sizeof(text_len));
    os.write(r.text.data(), text_len);
    size_t date_len = r.date.size();
    os.write(reinterpret_cast<const char*>(&date_len), sizeof(date_len));
    os.write(r.date.data(), date_len);
}

// 读单条review逻辑
void readReview(ifstream& is, review& r) {
    size_t text_len;
    is.read(reinterpret_cast<char*>(&text_len), sizeof(text_len));
    r.text.resize(text_len);
    is.read(r.text.data(), text_len);
    size_t date_len;
    is.read(reinterpret_cast<char*>(&date_len), sizeof(date_len));
    r.date.resize(date_len);
    is.read(r.date.data(), date_len);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:15:03