c++中数据文件处理中的分段错误

Segmentation fault in Data file handling in c++

本文关键字:分段 错误 文件 数据 c++ 处理      更新时间:2023-10-16

我用c++编写了一段小代码来理解数据文件处理。该程序包括接受条目、将条目写入.dat文件和搜索特定条目。到目前为止,只有写入功能在工作,读取和搜索功能给出了分段错误。怎么了?

#include<iostream>
#include<string>
#include<fstream>
#include<stdlib.h>
using namespace std;
class data_base
{
string name;
long int no;
public:
void input()
{
cout<<"nEnter name:";
cin>>name;
cout<<"Enter ph number:";
cin>>no;
}
void display()
{
cout<<name<<"t"<<no;
}
string retname()
{
return name;
}
long int retno()
{
return no;
}
};
void display_all()
{
data_base d;
fstream in;
in.open("database.dat",ios::in|ios::binary);
if(!in.is_open())
cout<<"Error opening file";
else{
while(in.read((char *)&d,sizeof(d)))
{
d.display();
}
}
in.close();
}
void search_name()
{
data_base d;
fstream in;
string s;
in.open("database.dat",ios::in|ios::binary);
if(!in.is_open())
cout<<"Error opening file";
else{
cout<<"nEnter name to be searched:";
cin>>s;
while (in.read((char *) &d,sizeof(d))) {
if(s==d.retname())
{
d.display();
}
}
}
in.close();
}
void search_no()
{
data_base d;
fstream in;
long int l;
in.open("database.dat",ios::in|ios::binary);
if(!in.is_open())
cout<<"Error opening file";
else{
cout<<"nEnter number to be searched:";
cin>>l;
while (in.read((char *) &d,sizeof(d)))
{
if(l==d.retno())
{
d.display();
}
}
}
in.close();
}
int main()
{
int ch;
fstream file;
data_base d,e;
string s;
while(1)
{
cout<<"1.Add entryn2.Search by namen3.Search by 
numbern4.Display all entries5.Exit"<<endl;
cin>>ch;
switch (ch) {
case 1: d.input();
file.open("database.dat",ios::out|ios::app|ios::binary);
if(!file.is_open())
cout<<"Error opening file";
else
{
file.write((char *)&d,sizeof(d));
cout<<"Entry added!"<<endl;
}
file.close();
break;
case 2:search_name();
break;
case 3:search_no();
break;
case 4:display_all();
break;
case 5: exit(0);
}
}
}
class data_base
{
string name;
...
}
...
data_base d;
...
file.write((char *)&d,sizeof(d));

你在这里已经注定了。std::string结构内部有一个指针。将这个指针重新解释为一个字符数组,可以得到一些字符序列。您可以将其保存到一个文件中,稍后再进行读取。

此时,您新读取的data_base变量具有与前一个完全相同的二进制表示。但现在std::string的内部指针不再指向有效的内存地址,因此出现segfault。

注意分段断层实际上是好的。在某些糟糕的情况下,内存地址是有效的,但它会指向一些完全无关的(随机)数据。这将是一个非常难以找到的错误。

你从一开始就做错了不要为了数据的序列化/反序列化而向char*进行强制转换。使用适当的序列化技术,例如将结构转换为xml、json、googleprotobuf,甚至提出一些自定义的东西。只是不要重新解释原始记忆。即使结构中没有指针,二进制表示也依赖于编译器、操作系统和cpu。