在动态分配char
时,我总是这样做:
char *pCh = malloc(NUM_CHARS * sizeof(char));
然而,我最近被告知,使用sizeof(char)
是多余的和不必要的,因为“根据定义,char
的大小是一个字节,”所以我应该/可以写以上这样的行:
char *pCh = malloc(NUM_CHARS);
我的理解是char的大小取决于目标计算机上使用的本机字符集。例如,如果本机字符集是ASCII,则char
是一个字节(8位),如果本机字符集是UNICODE,则char
将需要更多字节(> 8位)
为了提供最大的可移植性,是不是必须使用sizeof(char)
,因为malloc
只是分配8位字节?我误解了malloc
和sizeof(char)
吗?
答案 0 :(得分:14)
是的,它是多余的,因为语言标准指定sizeof (char)
是1.这是因为这是测量事物的单位,所以当然单位本身的大小必须是1。
生活变得奇怪,单位根据自己定义,这根本没有任何意义。许多人似乎“想要”假设“有8位字节,sizeof
告诉我有多少这样的特定值”。这是错误的,根本不是它的工作方式。确实,可能存在字符大于8位的平台,这就是我们CHAR_BIT
的原因。
通常情况下,总是“知道”当你分配字符时,但如果你真的想要包含sizeof
,你应该考虑让它使用指针,而不是:
char *pCh = malloc(NUM_CHARS * sizeof *pCh);
这“锁定”正在分配的东西的单位大小用于存储分配结果的指针。如果你看到这样的代码,这两种类型应该匹配:
int *numbers = malloc(42 * sizeof (float));
这是巨大的警告信号;通过使用sizeof
中左侧的指针,您无法做出那种类型的错误,我认为这是一个很大的胜利:
int *numbers = malloc(42 * sizeof *numbers);
此外,如果您更改指针的名称,malloc()
可能无法编译,如果您有(错误的)基本类型的名称,它将会编译。如果您忘记了星号(并写下sizeof numbers
而不是sizeof *numbers
),则存在轻微的风险,您将无法获得所需内容。在实践中(对我来说)这似乎永远不会发生,因为星号在这种模式中已经非常成熟,对我来说。
此外,这种用法依赖于(并强调)sizeof
不是函数的事实,因为指针解引用表达式周围不需要()
。这是一个很好的奖励,因为很多人似乎都想否认这一点。 :)
我发现这种模式非常令人满意,并推荐给每个人。
答案 1 :(得分:5)
C99 draft standard部分6.5.3.4
sizeof运算符段 3 声明:
当应用于具有char,unsigned char或signed char类型的操作数时, (或其合格版本)结果为1. [...]
在C11标准草案中,它是 4 段,但措辞是相同的。因此NUM_CHARS * sizeof(char)
应该等同于NUM_CHARS
。
我们可以从3.6
中的 byte 的定义中看出它是:
可寻址的数据存储单元,足以容纳基本字符的任何成员 执行环境的集合
和注2 说:
一个字节由一个连续的位序列组成,其数量是实现定义的。最低有效位称为低位;最重要的位称为高位。
答案 2 :(得分:4)
C规范声明sizeof(char)
是1
,因此只要您处理C的符合实现,它就是多余的。
malloc
使用的尺寸单位是相同的。 malloc(120)
为120 char
分配空间。
char
必须至少为8位,但可能更大。
答案 3 :(得分:3)
sizeof(char)
将始终返回1,因此无论您使用它还是尼特都无关紧要,它不会改变。您可能会将此与UNICODE宽字符混淆,后者有两个字节,但它们的类型wchar_t
不同,因此在这种情况下应使用sizeof
。
如果您正在处理一个字节定义为16位的系统,那么sizeof(char)
仍将返回1,因为这是底层架构将分配的内容。 1字节,16位。
答案 4 :(得分:3)
分配大小始终以char
为单位进行衡量,其大小为1 按定义。如果您使用的是9位计算机,malloc
将其参数理解为9位字节数。
答案 5 :(得分:2)
sizeof(char)
始终为1
,但不是因为char
始终是一个字节(不一定是),而是因为sizeof
运算符返回对象/类型大小,单位为char
。