fread() 应用于局部结构变量后函数 returns 时发生访问冲突

Access Violation when function returns after fread() applyed to a local struct variable

这是我程序的一部分。

void LookUpStuInfo(student stu[], int size, int ID) 
{   
    FILE *fp; 
    if((fp = fopen("stu_dat", "r")) == NULL)
    { 
        cout << "cannot open file" << endl;
        return; 
    } 

    struct student tmp;
    fread(&tmp, sizeof(struct student), 1, fp);
    fclose(fp);
}

stu_dat(由fwrite()创建)存储了几个struct student的信息。当此函数结束并且 returns 到 main() 函数时,发生访问冲突。

但是,如果我在这种情况下不使用局部结构变量,而是使用学生 stu[] 并将 fread() 应用于 &stu[0],则效果很好。那怎么了?

好吧,上面的代码足以产生访问冲突。我已经测试删除此 LookUpStuInfo() 中的所有其他代码,直到只剩下基本的读取和关闭,仍然无法正常工作。

下面是这个project.It的完整代码,如果您想了解main()struct student的详细信息,可能会对您有所帮助。

#include<iostream>
#include<string>
#include "stdio.h"
#define num 3
using namespace std;
struct student
{
    int ID;
    string name;
    string sex;
    string birthday;
    float score;
};
void SortStuArr(student stu[], int size)
{
    student tmp;
    for (int i = 0; i < size; i++)
        for (int j = (i + 1); j < size; j++)
        {
            if (stu[i].score < stu[j].score)
            {
                tmp = stu[i];
                stu[i] = stu[j];
                stu[j] = tmp;
            }
        }
    cout << "ID" << "    " << "Score" << endl;
    for (int i = 0; i < size; i++)
        cout << stu[i].ID << "\t" << stu[i].score << endl;
}
float GetAvgScr(student stu[], int size)
{
    float avg=0;
    for (int i = 0; i < size; i++)
        avg += (stu[i].score);
    avg = avg / size;
    return avg;
}
void LookUpStuInfo(const char* locat, int size, int ID)
{
    FILE *fp;
    if((fp=fopen("stu_dat","r"))==NULL)
    {
        cout << "cannot open file" << endl;
        return;
    }
    struct student tmp;
    for (int i = 0; i < size; i++)
    {
        fread(&tmp, sizeof(struct student), 1, fp);
        if (tmp.ID == ID)
        {
            cout << tmp.name << tmp.ID << tmp.sex << tmp.birthday << tmp.score << endl;
            fclose(fp);
        }
    }
    cout << "Not Found!" << endl;
    fclose(fp);
}
void WritetoFile(student stu[], int size)
{
    FILE *fp;
    if((fp=fopen("stu_dat","w+"))==NULL)
    {
        cout << "cannot open file" << endl;
        return;
    }
    for (int i = 0; i < size; i++)
        fwrite(&stu[i], sizeof(struct student), 1, fp);
    fclose(fp);
}



int main()
{
    student stu[num];
    for (int i = 0; i < num; i++)
    {
        cin >> stu[i].name >> stu[i].ID >> stu[i].sex >> stu[i].birthday >> stu[i].score;
    }
    cout << GetAvgScr(stu, num) << endl;
    WritetoFile(stu, num);

        LookUpStuInfo("stu_dat", num, 1000);
    return 0;
}

好吧,我已经测试过删除我程序中的所有 string,它工作正常。似乎 fread()string.

上操作的函数会出错

你不能 fread 变成像 student.name 这样的 std::string (或者从它写)。发生崩溃是因为您有一个损坏的字符串,当编译器试图将它复制到数组中时,一切都出错了。直接读入数组不会有帮助,因为您可能计划在某个时候访问数组的成员——此时一切都会再次消失。

你需要读入字符串的长度,然后读入字符串的字符。