C++ glibc检测到双重自由或损坏

C++ glibc检测到双重自由或损坏,c++,crash,glibc,C++,Crash,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_pr

下面的代码有什么问题。对于某些输入,它运行得很好,对于某些特殊输入,它崩溃了

#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();

}
#包括
#包括
#包括
使用名称空间std;
结构事件{
字符串日期、时间、内容;
bool是高优先级的;
};
int main(){
事件一、二;
一、高优先级=假;
char-tmp;
流输出文件(“事件”,ios::binary);
coutone.date;
时间;
coutone.content;
如果(tmp='t')
1.is_high_priority=true;
其他的
1.is_high_priority=false;
out_file.write((char*)&one,sizeof(one));
out_file.close();
_文件中的ifstream(“事件”,ios::binary);
read((char*)&two,sizeof(two));
库特
tmp
是一个本地未初始化变量,您正在使用它,如上所示

所以你的代码调用了未定义的行为。没有什么可以说的了

tmp
是一个本地未初始化变量,您正在使用它,如上所示


因此,您的代码调用未定义的行为。没有什么可以进一步说明。

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

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

正如@sth所指出的,复制指向文件的指针并重新解释嗯,在无重复的情况下结束

不过,我觉得还有更微妙的事情,如果我错了,请纠正我。 该程序并不总是在所有输入上崩溃。它甚至不依赖于字符串的长度。我试着用一些测试用例运行该程序

请注意,字符“space”被视为delimeter。即使您输入,空格后的字符也会被下一个字符串占用

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


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

正如@sth所指出的,将指针复制到文件并重新解释它们,最终导致无重复的情况

不过,我觉得还有更微妙的事情,如果我错了,请纠正我。 该程序并不总是在所有输入上崩溃。它甚至不依赖于字符串的长度。我试着用一些测试用例运行该程序

请注意,字符“space”被视为delimeter。即使您输入,空格后的字符也会被下一个字符串占用

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


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

即使删除了if-else块,问题仍然存在……因此,我认为这与此无关。@nikel:您的代码中还有更多问题(正如其他答案所指出的),但这并不意味着
tmp=='t'
是定义良好的(假设
tmp
是一个未初始化的变量).好吧,好吧..实际上我只是从一个更大的代码中去掉了这个,忘了去掉这个部分:-|。即使删除了if-else块,问题仍然存在…因此,我认为这与此无关。@nikel:您的代码中有更多的问题(正如其他答案所指出的),但这并不意味着
tmp='t'
定义良好(假设
tmp
是一个未初始化的变量).好吧,好吧..实际上我只是从一个更大的代码中去掉了这个,忘了去掉这个部分:-|。好吧,指针没有释放对吗?那么,为什么它不工作?它不应该仍然给出输出吗?@nikel:当
one
two
main
的末尾超出范围时,它们被释放。strin的析构函数gs将被调用,这将释放其动态内存。没关系,但崩溃的原因是什么?@nikel:两个“副本”中的刺痛其中的一个结构包含指向同一动态分配内存的指针。当第一个结构被销毁时,它将释放该内存。当第二个结构被销毁时,它将尝试释放同一内存。这就是从glibc得到错误的原因。@sth:我试着用不同的输入运行该程序。崩溃似乎是随机的,而不是随机的取决于输入字符串的长度。复制指针和重建肯定是个问题。但并非所有输入都会发生崩溃。这是怎么可能的?好吧,指针没有解除分配对吗?那么,为什么它不工作?它不应该仍然提供输出吗?@nikel:当
1
2
退出时,它们就会解除分配作用域位于
main
的末尾。将调用字符串的析构函数,这将释放其动态内存。没关系,但崩溃的原因是什么?@nikel:两个“副本”中的stings其中的一个结构包含指向同一动态分配内存的指针。当第一个结构被销毁时,它将释放该内存。当第二个结构被销毁时,它将尝试释放同一内存。这就是从glibc得到错误的原因。@sth:我试着用不同的输入运行该程序。崩溃似乎是随机的,而不是随机的取决于输入字符串的长度。复制指针和重建肯定是个问题。但并非所有输入都会发生崩溃。这怎么可能?
if(tmp == 't')