2010-12-06 52 views
2
typedef struct { 

    unsigned char b1, b2; 

} cont; 

cont buf[1024]; 

int main(int argc, char *argv[]) { 

     FILE* fp; 

     fp = fopen(argv[1], "rb") 

     if(fp!=NULL) 

      fread(buf, sizeof (cont), sizeof (buf), fp); 

      //do something with buf 
      return 0; 

} 

你好,我在尝试运行这个程序时遇到了分段错误错误。它曾经工作得很好,所有的突然的segm。出现错误错误。 fread函数调用正在产生错误。请帮帮我!fread出现分段错误。帮帮我!

+0

程序不会停止这样工作。你改变了什么?新的编译器版本?还有别的吗? – 2010-12-06 10:13:12

+0

没什么,我使用的Windows平台上NetBeans IDE和我使用在缓冲元件的cygwin克++编译器 – user532053 2010-12-06 10:16:11

+0

第三参数应该是数(它是1024),而不是它以字节为单位的大小(这是的sizeof(BUF)) – 2010-12-06 10:22:35

回答

0

总是检查返回值。你还知道如果你真的设法读取任何东西吗?

我想这可能是因为填充。 “cont”类型被定义为2字节大,但可能会被填充到4.但是这不应该引起问题,因为即使sizeof(cont)返回2或4,“buf”必须使用填充的大小,因此仍然够大。

3

您正在使用fread()错误 - arg#1是要读取的元素的大小,而arg#2是要读取的元素的数量(在您的情况下应为1024)。

因此,你所做的读取sizeof (cont) * sizeof (buf)字节,并且溢出缓冲区。

请参见:

http://www.opengroup.org/onlinepubs/009695399/functions/fread.html

的函数文档。

为了澄清,您希望读取1024个元素,但sizeof(buf)是2048(至少,如果结构由平台的ABI填充,则可能更多)。

例(编码,使得它们不依赖于元件的具体数目):

fread(buf, 1, sizeof(buf), fp); // fills the buffer (assuming it's buf[...]) 
fread(buf, sizeof(*buf), sizeof(buf)/sizeof(*buf), fp); // ditto 

即如果要通过sizeof()传递目标缓冲区的总大小,则另一个参数必须为1,而如果要传递数据结构的大小,那么另一个参数是适合这些参数的数量缓冲。

0

sizeof(buf)给你buf的总数,而不仅仅是它的元素数量。尽管如此,你永远不应该直接读入结构。如果你这样做,坏事就等着你。

也可以在其成员之间的任何位置填充结构,因此您甚至不知道您定义的结构的确切内存布局。

为了保持程序的可移植性和安全性,请始终按元素逐个读取文件并从中构建数据。

int i; 
for(i = 0; i < MAX_ELEMENTS && !feof(fil); ++i) { 
    int c1, c2; 
    c1 = fgetc(fil); 
    c2 = fgetc(fil); 

    if(c1 == EOF || c2 == EOF) 
     break; 

    buf[i].c1 = c1; 
    buf[i].c2 = c2; 
} 

这看起来乏味而冗长吗? 是的,但这是很有道理的。始终假定文件的内容可能已损坏。只是将文件读入内存假定是危险