使用'sizeof(char)'动态分配'char'冗余时?

时间:2013-12-19 14:19:24

标签: c unicode char malloc ascii

在动态分配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位字节?我误解了mallocsizeof(char)吗?

6 个答案:

答案 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