C ++清除结构异常的向量

时间:2018-05-16 14:06:25

标签: c++ vector ifstream

我定义了一个名为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 :(得分:4)

您的结构Part不是POD type而不是trivial,因此您无法像保存或加载它一样。

取其id成员,std::string对象通常包含指针,这是保存的内容。该指针在任何其他进程中都无效。

您需要使用serialization来保存和加载您的结构。

答案 1 :(得分:3)

E3

这是一个很大的代码味道和UB。 instream.read(reinterpret_cast<char*>(parts.data()), bytes); 拥有一个指向堆分配字符串(模SSO)的指针,但是当你尝试将它重新解释为表单文件时(假设你以相同的方式保存它),你只会得到一些垃圾值(因为它现在没有& #39; t指向任何有效的内存位置),所以当std::string尝试在析构函数中释放它时,它会像你经历的那样失败。你根本无法做你想做的事情。

我建议您为结构重载std::string。 ostream的相应istream& operator>> (istream& is, Part& p);也是如此。它应该很容易,因为所有<<字段都存在这种重载。