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

时间:2018-08-31 11:51:57

标签: c++ c++11

#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 a\n";  
    // 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)

2 个答案:

答案 0 :(得分:2)

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

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

std::string中的B也是一样,您不能简单地编写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;

答案 1 :(得分:1)

A不是trivially copyable type,因此不能假装它只是字节序列。

您将需要查看“序列化”以正确地将对象与二进制文件进行相互转换。