【问题标题】:Access violation error when getting input from a binary file从二进制文件获取输入时出现访问冲突错误
【发布时间】:2013-04-28 18:59:57
【问题描述】:

好的,所以我正在尝试从二进制文件中读取输入。我已经稍微更改了这段代码,但是在这个版本中,我遇到了访问冲突错误......所以它试图访问不存在的东西。这是我的问题区域的源代码:

void HashFile::fileDump (ostream &log)
{
    HashNode *temp = new HashNode;

    fstream bin_file;
    bin_file.open ("storage_file.bin", ios::in | ios::binary);  

    for(int i = 0; i < table_size; i++)
    {
        bin_file.seekg( i * sizeof(HashNode) );

        bin_file.read( (char *)&temp, sizeof(HashNode) );

        printDump(HashNode(temp->title, temp->artist, temp->type, temp->year,
        temp->price), log, i);
    }

    bin_file.close();
}

void HashFile::printDump(HashNode A, ostream &log, int N)
{
    log << "(" << N << ") " << A.title << ", " << A.artist
        << ", " << A.type << ", " << A.year << ", $"
        << setprecision(2) << A.price << endl;
}

我知道我应该进行某种错误检查。现在错误发生在 printDump 函数中。每当我尝试输出到日志时,我都会收到访问冲突错误。但是,我将日志更改为 cout,我的代码将运行良好。它将读取我正确创建的二进制文件,直到它到达最后一个元素。对于我一直在测试的内容,table_size 应该等于 5。所以我进入 for 循环,并且 i 递增,直到它达到 5,然后它继续运行。 table_size 正在更改为某个随机值,即使我没有实际接触过它。我是否以某种方式在内存中写入了 table_size 的地址?

这是我的节点的定义:

class HashNode
{
    public:
        HashNode();
        ~HashNode();
        HashNode(string title, string artist, string type, int year, float price);
        friend class HashFile;
    private:
        char title [35];
        char artist [25];
        char type [12];
        int year;
        float price;
};

【问题讨论】:

    标签: c++ binaryfiles access-violation


    【解决方案1】:

    这个

    bin_file.read( (char *)&temp, sizeof(HashNode) );
    

    应该是这样的

    bin_file.read( (char *)temp, sizeof(HashNode) );
    

    你对指针感到困惑。

    该代码是否真正起作用很大程度上取决于您未显示的Node 的定义。

    此外,由于 temp 永远不会被删除,因此代码会泄漏内存。最好不要像这样分配 temp

    void HashFile::fileDump (ostream &log)
    {
        HashNode temp;
    
        fstream bin_file("storage_file.bin", ios::in | ios::binary);  
    
        for(int i = 0; i < table_size; i++)
        {
            bin_file.seekg( i * sizeof(HashNode) );
    
            bin_file.read( (char *)&temp, sizeof(HashNode) );
    
            printDump(HashNode(temp.title, temp.artist, temp.type, temp.year, temp.price), log, i);
        }
    }
    

    不清楚为什么你觉得需要从 temp 创建一个新节点,为什么不直接将 temp 传递给 printDump?像这样

            printDump(temp, log, i);
    

    但是没有看到节点的定义我不能肯定。

    也不需要关闭文件,这是自动发生的,在构造函数中打开文件也更干净一点恕我直言。

    编辑

    好的,看到Node 的定义,这是我的建议

    void HashFile::fileDump(ostream &log)
    {
        fstream bin_file("storage_file.bin", ios::in | ios::binary);  
        for(int i = 0; i < table_size; i++)
        {
            bin_file.seekg(i * sizeof(HashNode));    
            HashNode temp;
            bin_file.read((char *)&temp, sizeof(HashNode));
            printDump(temp, log, i);
        }
    }
    

    我还会将 printDump 更改为使用 const 引用,这样可以避免复制 Node 对象(它非常大)。

    void HashFile::printDump(const HashNode& A, ostream &log, int N)
    {
        log << "(" << N << ") " << A.title << ", " << A.artist
            << ", " << A.type << ", " << A.year << ", $"
            << setprecision(2) << A.price << endl;
    }
    

    【讨论】:

    • 我添加了Node的定义。在这一点上,我有点质疑为什么我也以某种方式做事。我还在学习如何编程,所以请原谅我的新手错误。
    • @user2349812 没问题,指针很混乱。原始代码中的错误是当您使用 new 分配 temp 时已经有了一个指针,因此您不需要使用 &amp; 创建另一个指针。但在我最新建议的代码中,temp 不是指针,所以你需要&amp; 来创建一个指针以传递给读取。
    • 好的,我刚刚完成了所有的编辑(使它不将它们作为指针存储在二进制文件中)并且它完全运行了!非常感谢您的帮助和解释。
    猜你喜欢
    • 2015-02-18
    • 2017-02-26
    • 2018-08-31
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2019-07-16
    相关资源
    最近更新 更多