glibc 检测到双重释放或损坏



下面的代码有什么问题。它运行对于某些输入完全正常,对于某些特殊输入崩溃?

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

struct event { 
string date,time,content;
bool is_high_priority;
};

int main() {
event one,two;
one.is_high_priority=false;
char tmp;
ofstream out_file("events" , ios::binary );

    cout<<"nEnter Date(dd.mm) ";
    cin>>one.date;
    cout<<"nEnter Time(hh:mm:ss) ";
    cin>>one.time;
    cout<<"nenter content";
    cin>>one.content;
    if(tmp == 't') 
        one.is_high_priority = true;
    else
        one.is_high_priority = false;

    out_file.write((char*) &one, sizeof(one) );
    out_file.close();

    ifstream in_file("events" , ios::binary );
    in_file.read((char*)&two,sizeof(two));
    cout<<two.date<<" "<<two.time<<" "<<two.content<<" "<<two.is_high_priority;
    in_file.close();
}

它对这些输入崩溃了:输入日期(dd.mm) ankmjjdn md

输入时间(hh:mm:ss)输入内容NJS SJNSN

您不能只将std::string对象的字节保存到文件中,然后再重新加载它们。std::string包含指向动态分配内存的指针,您的保存/加载将仅复制指针本身,而不是指向的数据。

if(tmp == 't') 

tmp是一个局部未初始化的变量,您正在使用它,如上所示。

因此,您的代码调用未定义的行为。没有什么可以再说的了。

正如

@sth所指出的,将指针复制到文件并重新解释它们,最终会出现无重复的情况。

但是,我认为还有更微妙的东西,如果我错了,请纠正我。该程序并不总是在所有输入上崩溃。 它甚至不依赖于字符串的长度。我尝试使用一些测试用例运行该程序。

请注意,字符"空格"被视为分律。即使您输入,空格后的字符也会被下一个字符串占用。

因此,第三个字符串占用该值,直到"空格"剩余的输入(直到回车)仍在输入缓冲区上。

我怀疑当第二个对象从 istream 构造时,"空格"后面的字符串会覆盖指针,这会导致损坏检测。

最新更新