Программа работает отлично в первый раз, но интересно, seg ошибки во второй раз при чтении из класса из двоичного файла? - PullRequest
0 голосов
/ 15 июня 2019

Проблема, с которой я сталкиваюсь, заключается в том, что программа работает отлично в первый раз, а ошибки seg - во второй раз. Единственное отличие - это первый раз, когда создается двоичный файл, и второй раз, когда данные добавляются в двоичный файл.

#include <iostream>
#include <vector>
#include <fstream>

//count of the number of car classes written to bin file
int num_of_cars_written;
// This will be the class written to binary
class Car{
    public:
    std::string model;
    int num_of_wheels;
    std::vector<std::string> list_of_features;
    Car(std::string model, int num_of_wheels){
        this->model = model;
        this->num_of_wheels = num_of_wheels;
    }
    Car(){
        this->model = "";
        this->num_of_wheels = 0;
    }
};

void write_to_binary_file(Car& car){
    std::fstream ofile("cars.bin", std::ios::binary | std::ios::app | std::ios::out);
    ofile.write(reinterpret_cast<char*>(&car), sizeof(Car));
    ofile.close();
    ++num_of_cars_written;
}

std::vector<Car> read_bin_of_cars(std::string bin_file_path){
    std::vector<Car> car_list;
    std::fstream file(bin_file_path, std::ios::binary | std::ios::in);
    int size_of_file = sizeof(file);
    int number_of_cars_read_so_far = 0;
    Car* car;
    while(!file.eof()){
        file.read (reinterpret_cast<char*>(car), sizeof(Car));
        car_list.push_back(*car);
        number_of_cars_read_so_far += size_of_file / num_of_cars_written;
        if(number_of_cars_read_so_far >= size_of_file) break;
    }
    file.close();
    return car_list;
}

int main(){
    Car car_one("mazda", 4);
    car_one.list_of_features.push_back("cup holder");
    car_one.list_of_features.push_back("gps");
    Car car_two("honda", 4);
    Car car_three("sazuki", 2);
    car_three.list_of_features.push_back("leather seat");
    write_to_binary_file(car_one);
    write_to_binary_file(car_two);
    write_to_binary_file(car_three);
    std::vector<Car> list = read_bin_of_cars("cars.bin");
    for(auto car : list){
        std::cout << "**************Car Object**************\n";
        std::cout << car.model << std::endl;
        std::cout << car.num_of_wheels << std::endl;
        for (auto feature : car.list_of_features) {
            std::cout << feature << std::endl;
        };
    }
    return 0;
}

Вот результаты первого запуска

**************Car Object**************
mazda
4
cup holder
gps
**************Car Object**************
honda
4
**************Car Object**************
sazuki
2
leather seat

Вот результаты второго запуска

Segmentation fault (core dumped) (obviously)

EDIT: эта работа с первой попытки - неопределенное поведение и не должна работать. В комментариях перечислены лучшие способы написания и чтения в двоичном формате.

1 Ответ

0 голосов
/ 15 июня 2019

Есть несколько проблем с этим кодом. Обобщая несколько:

В write_to_binary_file:

write(reinterpret_cast<char*>(&car), sizeof(Car)); Это неправильный способ записи объекта в файл. Он будет просто писать в блоге памяти объекта car и не обязательно будет заботиться о членах, указывающих на выделения вне его (например, string или vector и т. Д. Не являются статическими массивами. Они, скорее всего, выделяют память вне объект. Прочитайте о сериализации и используйте его вместо этого.

В read_bin_of_cars:

Вы читаете в указатель car без выделения памяти для него. Опять же, даже после выделения памяти убедитесь, что вы используете сериализацию для чтения объекта из файла.

Имейте в виду, reinterpret_cast является наиболее опасным. Вы должны использовать его только тогда, когда вы знаете, что делаете. Приведение объекта прямо к символьному указателю является ошибкой.

Могут быть и другие проблемы с кодом. Это только я нашел с первого взгляда.

...