对fread的分割错误。救命!

时间:2010-12-06 09:59:37

标签: c++ c

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函数调用正在生成错误。请帮帮我!

3 个答案:

答案 0 :(得分: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,而如果要传递数据结构的大小,则另一个参数是这些参数的数量适合缓冲区。

答案 1 :(得分:0)

始终检查返回值。你怎么知道你是否真的设法阅读了什么?

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

答案 2 :(得分: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;
}

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