2011-05-12 184 views
2

約結構簡單的問題:C的結構:分段故障

struct xint { 
    int number; 
    char string[12]; 
}; 

int main(int argc, char *argv[]) 
{ 
    struct xint offsets, *poffsets; 
    poffsets=&offsets; 
    FILE * pFile = fopen("file","rb"); 
    fread(poffsets,1,16,pFile); 
    printf("Number %d\nString %s\n",offsets.number,offsets.string); 
} 

我得到這個輸出

Number 12345 
Segmentation fault 

我知道我可能已經做了一些錯誤的結構和指針和內存分配。在此先感謝:)

回答

0

您得到緩衝區溢出。您的字符串包含12個字符,但您沒有空間來終止'\0'

如果你做的事:

struct xint { 
    int number; 
    char string[16]; // Make sure you have enough space for the string + '\0'. 
}; 

int main(int argc, char *argv[]) 
{ 
    struct xint offsets, *poffsets; 

    // Initialize your memory to 0. This will ensure your string is 
    // '\0'-terminated. 
    // FYI, sizeof(xint) here is 20. 
    memset(&offsets, 0, sizeof(xint)); 

    poffsets=&offsets; 
    FILE * pFile = fopen("file","rb"); 
    fread(poffsets,1,16,pFile); 
    printf("Number %d\nString %s\n",offsets.number,offsets.string); 
} 

這將解決這個問題。

+0

它會隱藏問題。一個12個字符的字符串仍然會出現段錯誤(在OP的代碼中,或者在這個版本中是16)。 – Mel 2011-05-12 20:21:24

+0

我不知道你的意思是「它會隱瞞問題」。這段代碼工作得很好。我已經包含了整個代碼,所以你明白了。 「分配足夠的內存並確保您的字符串'\ 0'終止」的概念是當前上下文中的重點,而我的解決方案清晰地解決了這個問題。IMO – joce 2011-05-12 20:35:51

+0

啊,16是故意的。認爲這是一個錯字。問題是你的結構體大小現在與你的fread不同步,你通常將它編碼爲fread(poffsets,1,sizeof(struct xint),pFile)' – Mel 2011-05-12 22:39:39

0

我猜字符串在文件中沒有以null結尾,而且你的代碼也沒有做任何事情來終止字符串。

fread(poffsets, 1, 16, pFile); 
offsets.string[11] = '\0'; 
printf("Number %d\nString %s\n", offsets.number, offsets.string); 

或修改文件,以便字符串以空字節結尾。

+0

啊,小學生錯誤:)謝謝 – 2011-05-12 19:09:25

+0

\ 0字符爲NUL,指針爲NULL,否則字符串爲零終止,不以null結尾。小寫的null表示,從字面上看,沒有任何東西 - 與零相反,這是什麼都不代表。所以以null結束的字符串將是一個未終止的字符串。 ;)你讀過愛麗絲夢遊仙境,還是你熟悉馬格利特? 「這不是管子。」 – 2011-05-12 19:13:03

+0

該解決方案將覆蓋讀取字符串的最後一個字符。 – joce 2011-05-12 20:48:51

2

你的問題是你直接從文件讀入一個結構,而不檢查結構對齊。做到這一點,而不是:

fread(&offset.number,1,sizeof(offsets.number),pFile); 
    fread(&offset.string,1,sizeof(offsets.string),pFile); 
+1

如果字符串不是以0結尾的話,printf仍然會對此產生影響。 – joce 2011-05-12 19:11:28

+0

一個很好的技術,謝謝! – 2011-05-12 19:12:22

+0

'''&offset.string'''是多餘的 - 因爲offset.string已經是指向緩衝區的指針,因此會丟失'''&'''。 – 2011-05-12 19:14:54

1

我懷疑你正在閱讀的文件數據不終止與NUL'\0')字符的字符串。通過C標準庫的printf()字符串的C定義,字符串必須以NUL字符結尾。

您可能總是(通過代碼)確保.string[11] = '\0'

OR,申報string[13]並確保string[12] = '\0'

此外,另一個海報提到的結構成員對齊的擔憂。這是您必須解決的有效問題。