fread改变了参数的值?

时间:2015-01-26 17:45:56

标签: c

FILE *inp = fopen(...);
int j, buff;
j = 40 - sizeof(int) - 4;
printf("%d\n", j);
fread(&buff, j, 1, inp);
printf("%d", j);

由于某种原因,j为32,然后在第二次打印时跳转到某个疯狂的高位数。我对C很新,但不是编程,也不能解决这个问题。

2 个答案:

答案 0 :(得分:2)

fread的原型是

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

哪里

size这是要读取的每个元素的大小(以字节为单位)。

在你的情况下,你试图将32个字节读入4字节int,这是未定义的行为。

如果您有int buff[40];

buff可以容纳40个整数元素,因此调用可以像

fread(buff,sizeof(buff),1,inp);

答案 1 :(得分:1)

由于几乎可以肯定buff是一个本地数组,它是堆栈分配的,而fread会覆盖你的堆栈,包括j,因为最有可能40 - sizeof(int) - 4大于sizeof(buff)

是的 - 那是你的问题。 sizeof(buff) = sizeof(int),假设sizeof(int)为4,您要求读取40个字节,这将覆盖超过buff的36个字节。

如果你正在尝试读取一组int,你应该声明一个int数组(读取的数量不超过它的大小)。

如果您尝试阅读40个整数,则应该执行以下操作:

int buff[40];
size_t amountRead = fread(buff, sizeof(int), 40);

或者如果它让你开心。

int buff[40];
size_t size = sizeof(buff);
size_t amountRead = fread(buff, size, 1);

后者更好,因为代码将独立于buff的维度变化而工作。

只是为了避免将来的问题,看起来你可以使用fread读取和编写结构,你可以,但这不是一个可移植的序列化策略(主要是由于字节顺序,数据类型大小和不同计算机或编译器配置上的struct padding差异。)

看起来您可以使用fread序列化整数数组,但您可以,但由于数据类型大小差异和字节排序差异,它也不可移植。

只要您使用一台计算机,一台编译器,一组编译器设置,就可以了。