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
(或者从它写)。发生崩溃是因为您有一个损坏的字符串,当编译器试图将它复制到数组中时,一切都出错了。直接读入数组不会有帮助,因为您可能计划在某个时候访问数组的成员——此时一切都会再次消失。
你需要读入字符串的长度,然后读入字符串的字符。
这是我程序的一部分。
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
(或者从它写)。发生崩溃是因为您有一个损坏的字符串,当编译器试图将它复制到数组中时,一切都出错了。直接读入数组不会有帮助,因为您可能计划在某个时候访问数组的成员——此时一切都会再次消失。
你需要读入字符串的长度,然后读入字符串的字符。