[英]Segmentation fault when calling fread() c++
我不明白我犯的錯誤。 我嘗試了很多,但無法讀取我的文件。 基本上,我將一個結構寫入名為0.txt / 1.txt / 2.txt ...的文件中,該文件基於帳戶amound。 我確實花了很多時間來解決我的問題,但我不明白如何解決以及為什么會收到錯誤消息。 另外,我在用我的開發代碼(使用dev c ++)編譯代碼時沒有問題,但是當我按“加載帳戶”按鈕時,出現錯誤“ Segmentation Faul t”(使用Windows 7)。 我注意到問題出在函數ladeAccounts() 中的fread()行上。 我的結構的名稱是“ 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
值) fopen
(請參閱文檔 )可以出於不同的原因返回NULL
句柄。 如果在調用fread
之前未檢查句柄的有效性,則會出現分段錯誤。
正如您在上面鏈接的官方文檔中所看到的那樣,在大多數庫實現中, errno
變量可以幫助您提供有關故障的系統特定錯誤代碼。 這可以幫助您調試打開文件時的錯誤。
解決了我們代碼中的錯誤之后,您將遇到其他問題 。 正如人們(尤其是@Christophe)在其他答案中指出的那樣,您的代碼中存在結構性問題,因為您嘗試對非POD(又稱字符串)的文件對象進行序列化/反序列化。 由於字符串是復雜的對象,因此您無法直接對其進行序列化。
使用字符數組的方法將正常工作,因為可以按照您的編碼方式處理簡單類型。
因此,您可以使用std::string
c_str()方法從字符串中獲取以null結尾的char數組,並將其存儲在文件中。
相反的操作則更加直接,因為您可以僅通過傳遞反序列化的char數組來初始化std :: string:
std::string str(the_array);
您有一個問題,因為您使用fread()
加載二進制數據。 但這僅適用於普通舊數據(POD)對象。
它用較少的瑣碎對象給出災難性的結果,尤其是在這些對象的內部管理動態內存分配和/或指針的情況下,例如在字符串中就是這種情況。
順便說說:
如果您讀/寫二進制數據,則應該真正使用“ rb” /“ wb”作為fopen()
模式。 如果不這樣做,則沒有必要進行seg.fault,但是在某些系統上您的數據可能不正確。
編輯:
抱歉,我的閱讀不夠好:如果它恰好發生在fread()
上,那么Alex提供的原因肯定會有所幫助。 但是,我留下了這個答案,因為一旦您解決了fopen()
問題,如果嘗試使用已讀取的對象,則可能會遇到分段錯誤。 如果您沒有sizeof(iAccount)
,請查看sizeof(iAccount)
並將其與字符串內容的大小進行比較。
編輯 if(f2)是true,所以我錯了,文件成功打開了嗎?
我發現該文件未打開/ fopen無法處理路徑,例如0.txt。 我也嘗試直接輸入路徑而不構建它(沒有stringstream等)。 我仍然有分割錯誤的問題。 我檢查了文件在“帳戶”文件夾中是否存在的所有內容。 我在同一文件夾中有另一個名為“ 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);
}
那里我沒問題!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.