2011-05-12 183 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'

此外,另一个海报提到的结构成员对齐的担忧。这是您必须解决的有效问题。