我想知道sizeof(char)和sizeof(char *)之间是否有区别:
char *s;
s = malloc(sizeof(char*)*len + 1);
char *s;
s = malloc(sizeof(char)*len + 1);
这是相同的吗?
char
是一个字符类型,sizeof(char)
被定义为1。(N1570 6.5.3.4 The sizeof and _Alignof operators, paragraph 4)
char*
是指向字符的指针类型,sizeof(char*)
取决于环境。在32位环境中通常为4,在64位环境中为8。
在sizeof(char*) > sizeof(char)
的典型环境中,如果len
不足以引起整数溢出,则malloc(sizeof(char*)*len + 1)
将(至少尝试)分配比malloc(sizeof(char)*len + 1)
更多的内存。
s = malloc(len + 1)
就足够了。 - EsmaeelEchar*
是指向char
的指针。你误解了 char*
作为一个“类型”的意思。
char
是大小为1的类型,而指针 char*
在32位系统上可以为4,在64位系统上可以为8(如果按照系统进行编译)。首先,这是一个很好的例子,展示了在C语言中应该对malloc
进行强制类型转换。
让我们考虑一下这段代码片段。
char *s;
s = malloc(sizeof(char*)*len + 1);
阅读代码时不清楚作者的意图。他想要分配一个类型为char[sizeof(char*)*len+1]
的字符数组,还是他想分配一个类型为char*[len+1]
或char*[len]
的数组,但犯了一个错误?
很明显,在malloc(sizeof(char*)*len+1)
中这样的表达式会使读者感到困惑,并容易出错。
然而,如果作者写成如下形式:
s = ( char ** )malloc(sizeof(char*)*len + 1);
那么编译器将会报告一条诊断信息。或者如果他写了
s = ( char * )malloc(sizeof(char*)*len + 1);
那么,这将更清楚地表明作者的意图。
此外,在指针声明和分配内存的语句之间,可能会有许多屏幕行代码,最糟糕的是声明可能在一个文件中,而分配语句则在另一个文件中。
char *s;
//....
//....
s = malloc(sizeof(char*)*len + 1);
如果不进行强制转换,读取这样的代码非常耗时。
至于问题。 sizeof(char)
始终等于1,不依赖于使用的环境。而sizeof(char*)
是实现定义的,可以等于2、4或8字节,甚至其他一些值。
因此,在malloc中的这个表达式malloc(sizeof(char)*len + 1)
与这个调用中的表达式malloc(len + 1)
完全等价。再次强调,看到这个声明并不清楚。
s = malloc(len + 1);
动态分配的是什么类型的对象。无论是分配字符数组还是例如像char(*)[2]
和len+1
这样的二维字符数组-是否为偶数并且向len
添加1,因为len
是奇数或偶数,都会分配其他类型的对象。
因此最好写成
s = ( char * )malloc(sizeof(char)*len + 1);
^^^^^^^^^
这段代码是自我记录的,使其易于阅读。
因此,这两个语句之间的区别
s = malloc(sizeof(char)*len + 1);
s = malloc(sizeof(char*)*len + 1);
第一个语句分配了 len + 1
字节的内存空间,而第二个语句分配了 sizeof(char *) * len + 1
字节的内存空间,其中 sizeof(char *)
在非常罕见的情况下除外通常大于1。
char
不等于char *
;char
是一个字符,char *
是指向char
的指针。 - pzaengersizeof
给出的值。 - Some programmer dudesizeof (char)
= 1字节,sizeof (char *)
= 4 / 8字节。你需要问一下这两者之间的共同点,而不是它们的区别。 - i486