sizeof(char) 和 sizeof(char *) 的区别

Difference between sizeof(char) and sizeof(char *)

我想知道 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 sizeof 和 _Alignof 运算符,第 4 段)

char* 是一个 指向 字符的指针,sizeof(char*) 取决于环境。在 32 位环境中通常为 4,在 64 位环境中通常为 8。

sizeof(char*) > sizeof(char) 的典型环境中,如果 len 足够小不会导致整数溢出,malloc(sizeof(char*)*len + 1) 将(至少尝试)分配比 malloc(sizeof(char)*len + 1) 更多的内存.

它们不一样。 char* 是指向 char 的指针。您将 char* 本身误解为 "type"。

char大小为1,指针char*在32位系统上可以是4个,在64位系统上可以是8个(前提是按系统编译)

首先,这是一个很好的例子,表明malloc 应该在C中转换

让我们考虑一下这个代码片段

char *s;
s = malloc(sizeof(char*)*len + 1);

阅读它并不清楚代码的作者要做什么。他是想分配一个 char[sizeof( char * ) *len + 1] 类型的字符数组还是他想分配一个 char *[len + 1]char *[len] 类型的数组但出错了?

很明显,malloc 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);

不转换 malloc 阅读这样的代码非常耗时。

至于问题。 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 之类的二维字符数组 - 是偶数并且将 1 添加到 len 因为 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.