当回答对我的另一个答案here的评论时,我发现我认为可能是C标准中的一个洞(c1x,我没有检查过早期的那些和是的,我知道我不可能单独在这个星球上的所有居民中发现了标准中的错误。信息如下:
"The sizeof operator yields the size (in bytes) of its operand"
。"When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1"
。void *malloc(size_t sz)
,但所有内容都是"The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate"
。它根本没有提到用于论证的单位。CHAR_BIT
的最小值,因此字符的长度可以超过一个字节。我的问题很简单:
在char为16位宽的环境中,malloc(10 * sizeof(char))
将分配10个字符(20个字节)或10个字节?上面的第1点似乎表明前者,第2点表示后者。
任何拥有更多C-standard-fu的人都能得到答案?
答案 0 :(得分:16)
在16位char
环境中malloc(10 * sizeof(char))
将分配10 char
s(10个字节),因为如果char
是16位,那么该架构/实现定义一个字节为16位。 char
不是八位字节,它是一个字节。在较旧的计算机上,这可能比我们今天的8位 de-facto 标准更大。
C标准的相关部分如下:
3.6术语,定义和符号
byte - 可寻址的数据存储单元,足以容纳执行环境的基本字符集的任何成员......
注2 - 一个字节由一个连续的位序列组成,其数量是实现定义的。
答案 1 :(得分:2)
在C99标准中,字节char
和对象大小之间的严格相关性在6.2.6.1/4“类型表示 - 一般”中给出:
存储在任何其他对象类型的非位字段对象中的值由
n × CHAR_BIT
位组成,其中n
是该类型对象的大小(以字节为单位)。可以将该值复制到unsigned char [n]
类型的对象中(例如,通过memcpy);生成的字节集称为值的对象表示。
在C ++标准中,3.9 / 2“类型”中给出了相同的关系:
对于POD类型T的任何对象(基类子对象除外),无论对象是否保持类型T的有效值,构成对象的基础字节(1.7)都可以复制到数组中char或unsigned char。如果将char或unsigned char数组的内容复制回对象,则该对象应随后保持其原始值。
在C90中似乎没有明确提到的相关性,但在字节的定义,字符的定义和sizeof
运算符的定义之间,可以推断出{ {1}}类型相当于一个字节。
另请注意,字节中的位数(以及char
中的位数)是实现定义的 - 严格来说,它不需要是8位。并且onebyone在其他地方的评论中指出,DSP通常具有多个不是8位的字节。
请注意,IETF RFC和标准通常(总是?)使用术语'octect'而不是'byte'来明确他们所谈论的单位恰好有8位 - 不多也不少。
答案 2 :(得分:1)
在您的架构的可寻址单元中,“size_t sz”的单位是不是?我使用DSP,其地址对应32位值,而不是字节。 malloc(1)给我一个指向4字节区域的指针。