调用fread()c++时出现分段错误
Segmentation fault when calling fread() c++
我不明白自己犯的错误。我试了很多次,但无法阅读我的文件。基本上,我会根据账户金额在一个名为0.txt/1.txt/2.txt的文件中写入一个结构。我确实花了几个小时来解决我的问题,但我不明白如何解决,也不明白为什么会出现错误。此外,我在编译代码(使用dev c++)时没有问题,但当我按下加载帐户按钮时,我会得到错误"分段错误t"(使用windows 7)。我注意到问题出现在函数ladeAccounts()中的fred()行。我的结构的名称是"iAccount"。变量infoma类型为iAccount,newAccount()中类型为int anzahl的"现有帐户数"决定路径。
iAccount如下所示:
struct iAccount
{
string ID;
string password;
int level;
};
这就是我将STRUCT写入文件的方式:
void Account::newAccount(int anzahl, string username, string pw, int lvl)
{
iAccount neu;
neu.ID = username;
neu.password = pw;
neu.level = lvl;
ss.str("");
ss<<anzahl;
s = ss.str();
s = "Accounts/"+s+".txt";
f1 = fopen(s.c_str(), "w");
fseek(f1, 0, SEEK_SET);
fwrite(&infoma, sizeof(iAccount), 1, f1);
fclose(f1);
}
这就是我读取文件的方式(调用fread()时出现错误
void Account::ladeAccount(int nummer)
{
stringstream sa;
iAccount account_geladen;
sa.str("");
sa<<nummer;
s = sa.str();
s = "Accounts/"+s+".txt";
f2 = fopen(s.c_str(), "r");
fseek(f2, 0, SEEK_SET);
fread(&infoma, sizeof(infoma), 1, f2);
fclose(f2);
}
谢谢你的帮助。我不知道我的问题在哪里,正如我所说,我正在寻找几个小时。
编辑:文件打开了,我试过了(f2是真的!)。
编辑":ERRNO=0!!!
参见此处:
ostringstream Str;
Str << errno;
infoma.ID = Str.str();
这样做只是为了在我的wxtextlabel中查看errno的结果。
原因
您很可能是在NULL
文件句柄上调用fread
。所以这里有两个问题:
- 在代码中(不检查
fread
是否成功或返回NULL
值) - 由于某些原因无法打开您的文件(您应该调查…)
Explication
由于不同的原因,fopen
(请参阅文档)可以返回NULL
句柄。如果在调用fread
之前不检查句柄的有效性,则会出现分段错误。
小贴士
正如您在我上面链接的官方文档中所读到的,在大多数库实现中,errno
变量可以帮助您在失败时给出系统特定的错误代码。这可以帮助您调试打开文件时的错误。
次要问题
一旦你在我们的代码中解决了这个错误,你就会遇到其他问题。正如人们(尤其是@Christophe)在其他答案中所说,您的代码中存在结构问题,因为您试图对非POD文件对象(也称为字符串)进行序列化/反序列化。由于字符串是复杂的对象,所以不能直接序列化它们。
使用字符数组的方法将正确工作,因为简单的类型可以按照您的编码方式处理。
因此,可以使用std::string
c_str()方法从字符串中获取一个以null结尾的字符数组,并将其存储在文件中。
相反的操作甚至更简单,因为您可以初始化一个std::字符串,只需传递反序列化的字符数组:
std::string str(the_array);
您遇到了一个问题,因为您使用fread()
加载二进制数据。但这只适用于普通的旧数据(POD)对象。
它用来用不那么琐碎的对象来提供不稳定的结果,尤其是当这些对象的内部管理动态内存分配器和/或指针时,就像这里的字符串一样。
顺便说一下:
如果您读/写二进制数据,您应该真正使用"rb"/"wb"作为fopen()
的模式。如果你不这样做,你就不需要seg.fail,但你的数据在某些系统上可能不正确。
编辑:
对不起,我读得不够好:如果它发生在fread()
,亚历克斯提供的理由肯定会有所帮助。然而,我留下这个答案是因为一旦你解决了fopen()
问题,如果你试图处理你读到的对象,你可能会出现分割错误。如果您不满意,请查看sizeof(iAccount)
并将其与字符串内容的大小进行比较。
编辑如果(f2)为真,那么我错了,文件被成功打开了,对吗?
我发现文件没有打开/fopen无法处理路径,例如0.txt。此外,我尝试在不构建路径的情况下直接进入路径(没有字符串流等)。我仍然有分割错误的问题。我检查了"帐户"文件夹中存在的所有文件。我在同一文件夹中有另一个名为"Accounts.txt"的文件,读取现有帐户的数量(也使用结构)没有问题。在那里,我甚至不检查fopen是否成功,但它仍然有效。我稍后会为文件打开检查编写代码。
读取/写入Accounts/Accounts.txt的代码为:
struct init{
int anzahl_1;};
init anzahl;
FILE* f;
static string ss = "Accounts/Accounts.txt";
int account_anzahl1()
{
f = fopen(ss.c_str(), "r");
fread(&anzahl, sizeof(init), 1, f);
fseek(f, 0, SEEK_END);
fclose(f);
return anzahl.anzahl_1;
}
void account_anzahl_plus()
{
anzahl.anzahl_1 = anzahl.anzahl_1 +1;
f = fopen(ss.c_str(), "w");
fwrite(&anzahl, sizeof(init), 1, f);
fclose(f);
}
我没有问题!
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?