从文件中读取的数据,但发生核心转储错误

Data read from the file, but a core dumped error occurs

本文关键字:核心 转储 错误 文件 读取 数据      更新时间:2023-10-16
#include <iostream>
#include <fstream>
#include <vector>

class C{
private:
int work_loc, floor_no;
public:
C(){}
void printC(){
std::cout << "work Location: " << work_loc << "  floor_no: " << floor_no;
}
C(int work_loc1, int floor_no1): work_loc(work_loc1), floor_no(floor_no1){}
};
class B{
private:
int empid_;
std::string name_;
C obj_c;
public:
B(int empid, std::string name, int work_loc, int floor_no): empid_(empid), name_(name){
obj_c = C(work_loc, floor_no);
}
void printB(){
std::cout << empid_ << " " << name_ << "n ";
obj_c.printC(); 
}

};
class A{
private:
std::vector<B> calls;
public:
void addToCalls(B b){
calls.push_back(b);
}
void printAll(){
for(size_t i = 0; static_cast<int>(i) < 3; i++){
std::cout << "i is " << i << "n";
calls[i].printB(); 
}
}
int callSize(){
return calls.size();
}

};

int main(){
A a, c;
a.addToCalls(B(1,"a1", 1, 33));
a.addToCalls(B(2,"b2", 3 ,44));
a.addToCalls(B(3,"c2", 4, 55));
a.addToCalls(B(4,"d3", 5, 22));
a.addToCalls(B(5,"e4", 3, 88));
a.printAll();
std::cout << "end of an";  
// FILE* f;
// FILE* f1;
// f = std::fopen("serial.txt", "w+");
std::cout << "begin another a n  ";
std::fstream  f;
std::fstream  f2;
f.open("class_data.txt", std::ios::out|std::ios::binary);
f.write((char*)&a, sizeof(a));
// fwrite(a, sizeof(a), sizeof(a), f);
// fwrite(&n, sizeof(int), 1, f);
f.close();
// rewind(f);
// f.open("class_data.txt", std::ios::out | std::ios::binary);
f2.open("class_data.txt", std::ios::in | std::ios::binary);
f2.read((char*)&c, sizeof(c));
std::cout << "the size of C is " << c.callSize() << "n"; 
c.printAll();
// f.close();
f2.close();

}

在这里,我得到数据被复制到对象c中,但它给出了一个错误。 打印值后,代码会给出核心转储错误。 对象的值是从文件中复制的,该文件也是同时写入的。是因为 2 个文件指针打开同一个文件吗? 这是回溯

i is 0
1 a1
work Location: 1  floor_no: 33i is 1
2 b2
work Location: 3  floor_no: 44i is 2
3 c2
work Location: 4  floor_no: 55end of a
begin another a 
the size of C is 5
i is 0
1 a1
work Location: 1  floor_no: 33i is 1
2 b2
work Location: 3  floor_no: 44i is 2
3 c2
*** Error in `./a.out': double free or corruption (!prev): 0x000000000135fda0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fae6020e7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fae6021737a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fae6021b53c]
./a.out[0x4028ea]
./a.out[0x40276a]
./a.out[0x402564]
./a.out[0x4021e3]
./a.out[0x401c80]
./a.out[0x401ad6]
./a.out[0x401635]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fae601b7830]
./a.out[0x4010c9]
======= Memory map: ========
00400000-00404000 r-xp 00000000 fc:02 17574813                           /home/local/Serialisation/a.out
00603000-00604000 r--p 00003000 fc:02 17574813                           /home/local/Serialisation/a.out
00604000-00605000 rw-p 00004000 fc:02 17574813                           /home/local/Serialisation/a.out
0134e000-01380000 rw-p 00000000 00:00 0                                  [heap]
7fae58000000-7fae58021000 rw-p 00000000 00:00 0 
7fae58021000-7fae5c000000 ---p 00000000 00:00 0 
7fae5fe8e000-7fae5ff96000 r-xp 00000000 fc:00 1573048                    /lib/x86_64-linux-gnu/libm-2.23.so
7fae5ff96000-7fae60195000 ---p 00108000 fc:00 1573048                    /lib/x86_64-linux-gnu/libm-2.23.so
7fae60195000-7fae60196000 r--p 00107000 fc:00 1573048                    /lib/x86_64-linux-gnu/libm-2.23.so
7fae60196000-7fae60197000 rw-p 00108000 fc:00 1573048                    /lib/x86_64-linux-gnu/libm-2.23.so
7fae60197000-7fae60357000 r-xp 00000000 fc:00 1573053                    /lib/x86_64-linux-gnu/libc-2.23.so
7fae60357000-7fae60557000 ---p 001c0000 fc:00 1573053                    /lib/x86_64-linux-gnu/libc-2.23.so
7fae60557000-7fae6055b000 r--p 001c0000 fc:00 1573053                    /lib/x86_64-linux-gnu/libc-2.23.so
7fae6055b000-7fae6055d000 rw-p 001c4000 fc:00 1573053                    /lib/x86_64-linux-gnu/libc-2.23.so
7fae6055d000-7fae60561000 rw-p 00000000 00:00 0 
7fae60561000-7fae60577000 r-xp 00000000 fc:00 1573314                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fae60577000-7fae60776000 ---p 00016000 fc:00 1573314                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fae60776000-7fae60777000 rw-p 00015000 fc:00 1573314                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fae60777000-7fae608e9000 r-xp 00000000 fc:00 4718942                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fae608e9000-7fae60ae9000 ---p 00172000 fc:00 4718942                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fae60ae9000-7fae60af3000 r--p 00172000 fc:00 4718942                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fae60af3000-7fae60af5000 rw-p 0017c000 fc:00 4718942                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fae60af5000-7fae60af9000 rw-p 00000000 00:00 0 
7fae60af9000-7fae60b1f000 r-xp 00000000 fc:00 1573031                    /lib/x86_64-linux-gnu/ld-2.23.so
7fae60cf9000-7fae60cfe000 rw-p 00000000 00:00 0 
7fae60d1b000-7fae60d1e000 rw-p 00000000 00:00 0 
7fae60d1e000-7fae60d1f000 r--p 00025000 fc:00 1573031                    /lib/x86_64-linux-gnu/ld-2.23.so
7fae60d1f000-7fae60d20000 rw-p 00026000 fc:00 1573031                    /lib/x86_64-linux-gnu/ld-2.23.so
7fae60d20000-7fae60d21000 rw-p 00000000 00:00 0 
7ffd8c65f000-7ffd8c681000 rw-p 00000000 00:00 0                          [stack]
7ffd8c7a7000-7ffd8c7a9000 r--p 00000000 00:00 0                          [vvar]
7ffd8c7a9000-7ffd8c7ab000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
work Location: 4  floor_no: 55Aborted (core dumped)

您的类A具有类型std::vector的成员。您不能只是将std::vector作为二进制数据写入文件并期望能够将其读回。

您需要写入和读取std::vector的每个成员。

B中的std::string也是如此,你不能简单地编写std::string对象,你需要编写底层data,然后在读取数据时从中构造一个新的std::string

您可以为类定义自己的<<>>运算符,并将它们用于流,如下所示:

std::ostream& operator<< (std::ostream& stream, const A& a) 
{
// Write data from a to stream
return stream;
}
std::istream& operator>> (std::istream& stream, A& a)  
{  
// Read data from stream to a
return stream;
}

然后,您不必f.write((char*)&a, sizeof(a));,只需执行f << a;

A不是一个普通的可复制类型,所以假装它只是一个字节序列是行不通的。

您需要研究"序列化"以正确地将对象转换为二进制文件或从二进制文件转换对象。