为什么有些POSIX函数会获得元素编号和元素大小参数?
请参阅: http : //pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
malloc函数只是获取要分配的数组大小。
但是: http : //pubs.opengroup.org/onlinepubs/009695399/functions/calloc.html
并且: http : //pubs.opengroup.org/onlinepubs/009695399/functions/fread.html
只是两个接收元素大小和元素数量的函数示例。
为什么会有这种差异? 获得尺寸不是更简单吗?
这更像是一个注释而不是一个原因,但是就fread(3)
和fwrite(3)
的返回值而言, size
和nmemb
的值确实有所不同。 它们返回读取或写入的元素数,其中每个元素的size
由size
参数确定。
POSIX还说了以下几点。 fread()
,
如果读取了部分元素,则其值未指定。
,因此理论上,当读取的数据量不是size
的倍数时(由于文件结束或错误), size
的值也会对您获得的数据产生影响。
对于calloc()
,GNU C库(glibc)简单地将size
和nmemb
放在一起,同时检查溢出(使用技巧快速检测大多数不会溢出的size
和nmemb
对)。 这是来自glibc 2.20的相关代码(来自malloc / malloc.c中的 __libc_calloc()
。 nmemb
和size
分别称为n
和elem_size
。):
/* size_t is unsigned so the behavior on overflow is defined. */ bytes = n * elem_size; #define HALF_INTERNAL_SIZE_T \ (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2)) if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) { if (elem_size != 0 && bytes / elem_size != n) { __set_errno (ENOMEM); return 0; } }
之后从未引用过n
和elem_size
。 而是使用bytes
。
fread()
实现( libio / iofread.c中的 _IO_fread()
)类似地将nmemb
和size
放在一起,并且仅使用它们来计算之后的返回值。 (与calloc()
不同,它不检查溢出。)
我猜测有两个参数可能是历史的原因。 我也会对答案感兴趣。 也许size
参数在fread()
和fwrite()
某个点指定了每个I / O操作的块大小(或作为提示fwrite()
。
更新 : 这个答案和评论有一些有趣的讨论。 calloc()
。
我认为在calloc
和fread
函数中需要将值放在数组的元素中,所以如果它一次性放置它们必须逐个放置这可能会导致问题,因为你的cpu可能在[little-endian]中( http:// en.wikipedia.org/wiki/Endianness )订单。
例如,如果要在little-endian机器中将四个元素设置为1:
元素大小= 2字节:
| 01 00 | 01 00 | 01 00 | 00 01 |
元素大小= 3字节:
| 01 00 00 | 01 00 00 | 01 00 00 | 01 00 00 |
而对于fread
,这是基于如何实施fread。 单UNIX规范说
对于每个对象,应对fgetc()函数进行大小调用,并按顺序读取存储在unsigned char数组中的结果,该数组与对象完全重叠。