码迷,mamicode.com
首页 > 编程语言 > 详细

Bug记录 | C++对二进制文件录入、读取结构体数组遇到0xC0000005错误

时间:2020-05-27 15:50:14      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:cat   alt   ifstream   分析   for   调试   成功   编译器   str   

题目描述: 用I/O流类和对象的方法、C++的方法对文件进行读写操作。数据存放在结构体中,然后使用ofstream输出流对象的方法将学生成绩写入一个文本文件(自己打开它检查成功否),然后使用ifstream输入流对象的方法将数据文件的内容读取出来,最后将这些值打印显示(使用C++语句)
分析: 题目的要求很简单, 使用IO库中给定的函数即可. 相关函数包括write read等, 可查到函数原型如下所示:

技术图片 技术图片 注意, 由于ifstream(ofstream)从istream(ostream)继承而来, ifstream(ostream)实际上使用父类的read\write函数. 对read函数, 第一个参数是读取的字符数组, 第二个是要读取的字符数. 当遇到文件结束或者在文本模式文件中遇到文件结束标记字符时读结束. 由此, 可以写出如下的代码:

//
// Created by hellcat on 2020.05.27.
//

#include <iostream>
#include <fstream>
using namespace std;

typedef struct student {
    string name;
    int exam[4];
}STU;

int main() {
    STU stu[] = {
            { "张明明", 101, 67, 78, 82 },
            { "李天天", 102, 78, 91, 88 },
            { "王酷", 104, 56, 45, 77 },
            { "陈跑", 105, 67, 38, 47 }
    };

    string filename = "test.dat";
    ofstream out(filename, ios_base::binary);
    out.write(reinterpret_cast<char*>(&stu), sizeof(stu));
    out.close();

    ifstream in(filename, ios_base::binary);
    if(in) {
        STU __stu[4];
        in.read(reinterpret_cast<char*>(&__stu), sizeof(__stu));
        for(auto i : __stu) {
            cout<<i.name<<" ";
            for(auto j : i.exam)
                cout<<j<<" ";
            puts("");
        }
    }
    else
        cout<<"Error: Can‘t open file ‘test.dat‘. "<<endl;
    in.close();
}

运行结果: 技术图片 虽然得到了输出, 但是返回的代码却是-1073741819 (0xC0000005), 这意味着程序并没有正常退出. 在Google中搜索, 也没有得到返回代码的错误信息. 技术图片 1 (注: https://suying666.net/auth/register?code=yWhK 暂时有mian fei google工具) 但Google上有很多提示可能是编译器问题, 所以先换个环境, 使用linux环境在线编译器: 技术图片 发现有大量的Error, 而 技术图片 这里的Memory Map有暗示似乎存在内存上的一些错误.

下面进一步调试代码, 分别注释掉write和read的部分, 观察哪个部分出了问题. 注释掉read代码时, 成功得到了期望的退出代码0: 技术图片 很显然, 问题出在read上.

在看read的参数传入, 有一个sizeof(__stu)的存在, 而__stu中又包含有string. 但此时string大小并不确定, string中仅有两根指针. 很明显, 问题出现在string上.

那么, 将name改为C风格字符串, 固定大小, 问题迎刃而解:

//
// Created by hellcat on 2020.05.27.
//

#include <iostream>
#include <fstream>
using namespace std;

typedef struct student {
    char name[10];
    int exam[4];
}STU;

int main() {
    STU stu[] = {
            { "张明明", 101, 67, 78, 82 },
            { "李天天", 102, 78, 91, 88 },
            { "王酷", 104, 56, 45, 77 },
            { "陈跑", 105, 67, 38, 47 }
    };

    string filename = "test.dat";
    ofstream out(filename, ios_base::binary);
    out.write(reinterpret_cast<char*>(&stu), sizeof(stu));
    out.close();

    ifstream in(filename, ios_base::binary);
    if(in) {
        STU __stu[4];
        in.read(reinterpret_cast<char*>(&__stu), sizeof(__stu));
        for(auto i : __stu) {
            cout<<i.name<<" ";
            for(auto j : i.exam)
                cout<<j<<" ";
            puts("");
        }
    }
    else
        cout<<"Error: Can‘t open file ‘test.dat‘. "<<endl;
    in.close();
}

技术图片 最后, 经过2小时的探索Bug成功解决! 求解过程中也请教了我的C++老师, 在此表示感谢!!

Bug记录 | C++对二进制文件录入、读取结构体数组遇到0xC0000005错误

标签:cat   alt   ifstream   分析   for   调试   成功   编译器   str   

原文地址:https://www.cnblogs.com/tedukuri/p/12972929.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!