【问题标题】:System.AccessViolationException with a regular fileSystem.AccessViolationException 与常规文件
【发布时间】:2014-12-16 03:56:06
【问题描述】:

我在这段代码中遇到了异常: Project4.exe 中出现“System.AccessViolationException”类型的未处理异常

附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。

但它不是受保护文件或只读文件!!! ,当我使用文本文件时,错误消失了

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

struct student{
    string name;
    int age;
};

int main(){
    student s1, s2, s3;
    s1.name = "basel";
    s1.age = 20;
    ofstream in;
    in.open("example.std" ,ios::binary);
    in.write((char*)&s1, sizeof(s1));
    in.close();
    ifstream out;
    out.open("example.std" ,ios::binary);
    out.read((char*)&s2, sizeof(s2));
    cout << s2.name;
    return 0;
}

任何人都可以帮忙!!!

【问题讨论】:

  • 'System.AccessViolationException' 是 C++/clr 异常(您可以调整项目设置)
  • .. 它不是指文件 i/o,而是指进程中的内存访问(如您可能尝试写入或读取的错误描述中所述)或来自无效的内存区域)

标签: c++ visual-c++


【解决方案1】:

正如我在评论中提到的,抛出异常是因为您试图写入或读取无效的内存位置。

在您的情况下,最可能的罪魁祸首是:

out.read((char*)&s2, sizeof(s2));

您是否尝试过使用调试器单步执行代码?哪条线路故障?

您正在尝试将结构序列化,然后反序列化为文件。但几乎可以肯定存在一些导致问题的对齐问题(以及 name 成员是指向另一个数据结构的指针这一事实)

您可以修改代码以逐个成员序列化结构的内容,然后以类似的方式反序列化:

// Serialize 
ofstream out;
out.open("example.std", ios::binary);
out.write(s1.name.c_str(), sizeof(char)*s1.name.size());
out.write((char*)&s1.age, sizeof(int));
out.close();

现在是棘手的部分:反序列化。你怎么知道字符串有多长?您是否应该假设字符串与文件一样长,减去用于存储年龄的 4 字节整数?

【讨论】:

  • 当调试器到达 return 0 @Mike 时,错误出现在程序末尾
【解决方案2】:

在您的代码中,您尝试将结构存储到文件中并在您声明结构时将其读回:

struct student{
    string name;
    int age;
};

正如您的代码所建议的,您还想存储字符串“name”的内容,但是

in.write((char*)&s1, sizeof(s1));

不会将字符串的内容写入文件,因为 std::string 内部包含指向内容的指针,您只是将指针的值写入文件。因此,当你读取它备份时,你会得到内存错误。

要归档您想要的内容,您可以在结构中使用固定大小的字符数组。

【讨论】:

  • 感谢您在将名称更改为 char* 后正常工作 ^_^ @Matt
  • 有没有办法使用字符串来做到这一点? @马特
猜你喜欢
  • 2012-04-15
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
相关资源
最近更新 更多