这段代码存在几个问题。其中一些问题将导致编译失败,而其他问题可能会导致不稳定的行为。由于不稳定的行为可能不容易被注意到,因此我将首先解决这个问题。
在尝试使用 malloc
返回值之前,您应始终检查它。 例如:
Product *obuff = malloc(sizeof *obuff);
if (obuff == NULL) {
/* obuff can't be used because allocation failed */
return;
}
回复内容存在敏感词^**$、
realloc
或
calloc
分配的内存时,可以通过使用
free
来避免内存泄漏...
另一个相关的问题是,除非fread
的返回值表示成功,否则不应使用obuff->code
、name
、quality
和price
的值。
fread(&obuff->code, sizeof(obuff->code), 1, fp);
fread(&obuff->name, sizeof(obuff->name), 1, fp);
这将编译,但是您不需要和事实上不应该在此处使用“&”符号。表达式“obuff->code”和“&obuff->code”都指向同一位置(因为“obuff->code”是一个数组),但它们指向的对象类型不同;“obuff->code”指向数组的第一个字节,而“&obuff->code”指向整个数组。
fread(&obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(&obuff->price, sizeof(obuff->price), 1, fp);
这将编译通过,并且为了澄清,在这里你确实需要使用“&”符号,但是需要说明的是,在不同的系统上,short int和double可能具有不同的表示形式。你需要通过对这些字段进行串行化来形成文件中一致的表示形式。串行化是一个冗长的主题,更适合放在软件设计书的章节中进行讨论,所以为了简洁起见,我将继续进行,除非在此处提出进一步的具体问题。
这是不可移植的,在您提供的代码中没有真正的需要。
printf("%s %s %d %.2f\n", obuff.code, obuff.name, obuff.quantity, obuff.price);
预期%s
对应一个字符串指针;字符串是以第一个'\0'
字符结尾的字符序列。但是,您的代码没有显式分配任何'\0'
字符,因此我们无法保证obuff.code
和obuff.name
是字符串。如果它们不是,行为是未定义的(或者如我所描述的那样不稳定)。也许您想使用%15s
和%50s
分别表示它们可能是字符串,但如果不是,有最大长度吗?
这也是编译错误的来源。请注意,在之前的代码片段中,您引用了
obuff->code
、
obuff->name
等内容,而在此片段中,您引用了
obuff.code
等内容。点运算符(
.
)用于访问结构体的字段,而箭头运算符(
->
)用于访问指向的结构体的字段……也许您在这里应该使用箭头运算符?