C ++ четкий вектор исключения структур - PullRequest
0 голосов
/ 16 мая 2018

Я определил структуру с именем Part:

struct Part
{
    std::string id;
    double area;
    double volume;

    bool operator==(const Part& part) const
    {
        return (area == part.area) && (volume == part.volume);
    }

    bool operator!=(const Part& part) const
    {
        return !operator==(part);
    }

    bool operator<(const Part &part) const
    {
        return (area + volume) < part.area + part.volume;
    }
};

Я создал вектор частей и сохранил вектор в двоичном файле. Затем я читаю двоичный файл в вектор. Я подтвердил, что все части правильно прочитаны в векторе. Моя функция для чтения двоичного файла:

static bool restore_vector_from_file(const char* fileName, std::vector<Part> &parts) {

    std::ifstream instream(fileName, std::ios::in | std::ios::binary);

    if (!instream) {
        return false;
    }

    instream.seekg(0, instream.end);
    int bytes = instream.tellg();
    instream.seekg(0, instream.beg);

    int vector_size = bytes / sizeof(Part);
    parts.resize(vector_size);
    instream.read(reinterpret_cast<char*>(parts.data()), bytes);

    if (!instream) 
    {
        return false;
    }

    instream.close();
    return true;
}

Моя основная функция:

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "Number of arguments must be 3" << std::endl;
        return 1;
    }

    // Load parts with properties to a vector
    const char* folderName = argv[1];
    const char* vectorFileName = argv[2];

    std::vector<Part> partArray;

    // Load from pre-saved file to save time
    if (!restore_vector_from_file(vectorFileName, partArray))
    {
        std::cout << "Failed to retore vector from file" << std::endl;
        return 1;
    }
    partArray.clear();
    return 0;
}

Все отлично работает, пока я не попытаюсь очистить partArray. Выдает исключение:

Exception thrown: read access violation.
_Pnext was 0x1BC586CCB48.

Даже если я удаляю partArray.clear(), то же исключение выдается, когда return 0;

Пожалуйста, помогите.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Ваша структура Part не является типом POD и не тривиальным , поэтому вы не можете сохранить или загрузить ее, как делаете.

Взять его id член, объект std::string обычно содержит указатель , который является тем, что сохраняется. Этот указатель не будет действительным в любом другом процессе.

Вам необходимо использовать сериализацию , чтобы сохранить и загрузить вашу структуру.

0 голосов
/ 16 мая 2018
instream.read(reinterpret_cast<char*>(parts.data()), bytes);

Это большой запах кода и UB. std::string содержит указатель на выделенную кучу строку (по модулю SSO), но когда вы попытаетесь повторно интерпретировать его файл формы (при условии, что вы сохранили его таким же образом), вы просто получите некоторое значение мусора (так как теперь оно не указывает на любое действительное место в памяти), поэтому, когда std::string попытается освободить его в деструкторе, он потерпит неудачу, как вы уже видели. Вы просто не можете делать то, что вы пытаетесь сделать здесь.

Я предлагаю вам перегрузить istream& operator>> (istream& is, Part& p); для вашей структуры. И соответствующий << для ostream также. Это должно быть легко, поскольку такие перегрузки уже существуют для всех полей Part.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...