【问题标题】:c++: exception error after closing console appc ++:关闭控制台应用程序后出现异常错误
【发布时间】:2015-03-16 10:11:10
【问题描述】:

我正在学习 c++,并且有一个关于读写对象到文件的问题。

我创建了一个名为 Person 的类。在我的主文件中,我创建了 Person 类的两个实例。我将实例一写入名为“person.dat”的文件,然后将其读回我创建的第二个实例。一切都按预期工作,只是在程序关闭后抛出异常。我不确定是什么原因造成的。

异常:在 0x55ABDF62 (msvcp120d.dll) 处未处理的异常 写入二进制 Objects.exe: 0xC0000005: 访问冲突写入 位置 0xFEEEFEEE。

有人可以帮我解释一下吗?

代码:Person.h

#include <iostream>
#include <string>

using namespace std;

class Person {
    private:
        string name;
        string surname;
        int age;
    public:
        Person();
        Person(string, string, int);
        void setName(string);
        void setSurname(string);
        void setAge(int);
        string getName();
        string getSurname();
        int getAge();
};

Person::Person() {}

Person::Person(string _name, string _surname, int _age) {
    setName(_name);
    setSurname(_surname);
    setAge(_age);
}

void Person::setName(string _name) {
    name = _name;
}

void Person::setSurname(string _surname) {
    surname = _surname;
}

void Person::setAge(int _age) {
    age = _age;
}

string Person::getName() {
    return name;
}

string Person::getSurname() {
    return surname;
}

int Person::getAge() {
    return age;
} 

代码:Program.cpp

#include <iostream>
#include <fstream>

#include "Person.h"

using namespace std;

int main() {

    //create person 1
    Person person;
    person.setName("Kobus");
    person.setSurname("Beets");
    person.setAge(24);

    //write person 1 to file
    ofstream out;
    out.open("person.dat", ios::binary);    
    out.write(reinterpret_cast <char *> (&person), sizeof(person));
    out.close();    

    //create person 2
    Person person2;
    person2.setName("John");
    person2.setSurname("Doe");
    person2.setAge(26);    

    //read person 1 from file into person 2
    ifstream in;
    in.open("person.dat", ios::binary);
    in.read(reinterpret_cast <char *> (&person2), sizeof(person2));
    in.close();

    //print new person 2
    cout << " " << person2.getName() << " " << person2.getSurname() << " is " << person2.getAge() << " year(s) old... \n\n ";

    system("pause");

    return 0;
}

【问题讨论】:

  • 请注意,在 Windows 下存在结构化异常(SEH - 结构化异常处理),这就是您在此处看到的。它们不同于 C++ 异常
  • 现在更有意义了。谢谢你。我什至不知道它会发生在那个级别上。我想每件事都有第一次。干杯。

标签: c++ binary ifstream ofstream


【解决方案1】:

您不能以这种方式直接将对象写入文件,除非您有 POD 样式的数据结构(例如,只有简单的 C 数据类型或其结构/类,没有指针,没有 C++ 数据类型)。

在您的情况下, Person 有两个 std::string 成员,它们本身包含指针和其他东西,一旦写入文件并重新读取到内存,它们就会失去意义。

您需要添加更多逻辑来编写实际的字符串内容(参见 std::string::c_str()、std::string::data()、std::string::size())。

异常可能是由 std::string 析构函数引起的,它试图释放或访问已经释放的内存。

【讨论】:

  • 我用一个简单的结构测试了相同的读写方法,其中只有两个 int 值,它似乎可以在没有抛出异常的情况下工作。谢谢(你的)信息。我将查看您提供的信息,看看如何在我的程序中使用它。我当然也需要能够将字符串写入二进制文件。
  • 一个带有 to int 的简单结构将是 POD 并且不包含任何指针。您可以查看 std::string github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/… 的(有些晦涩的)来源。第114行有一个成员_M_dataplus,实际上是一个指针——这会导致这里的问题。
  • 如果需要写数据,可以考虑写长度,后跟数据之类的。
  • 所提供的链接实际上是 GNU c++ 库的源代码,但对于 Microsoft/Visual Studio 来说类似。
猜你喜欢
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
相关资源
最近更新 更多