将malloc的结果转换为char(不是char *) - 为什么编译器没有抱怨?

时间:2013-03-27 22:44:46

标签: c casting

tmpString = (char*)malloc((strlen(name) + 1) * sizeof(char));
tmpString = (char )malloc((strlen(name) + 1) * sizeof(char));

这两行之间有什么区别?

我的理解是第二行是错误的,但由于某种原因,编译器什么也没说。

4 个答案:

答案 0 :(得分:5)

第一行转换(void)指针,malloc返回指向char的指针,从而保留其指针。所有它告诉编译器“位置X的内存应该被视为一个字符数组”。

第二次演员将malloc返回的指针转换为单个字符。这有多种原因:

  • 当你把指针变成完全不同的东西时,你失去了指针
  • 你也失去了指针的大部分数值,因为字符的大小远小于指针的大小(在很多情况下,指针的大小是32位或64位但是字符只有8位)并且“多余”位被丢弃。

我认为警告级别提高到足够高的编译器应警告第二次分配。

答案 1 :(得分:2)

第二行是错误的(转换为char会将指针截断为只有一个字节,使数据tmpString包含无效的地址),但是C中的所有强制转换都是未经检查的,所以你'永远不会得到错误。

答案 2 :(得分:2)

是的,第二行有未定义的行为。由于案例是明确的,编译器只是假设您知道自己在做什么。实质上,第二个转换将指针值的第一个字节解释为字符代码。最后一句话只是说明性的 - 你甚至不能完全依赖于那种情况。

答案 3 :(得分:0)

假设tmpString的类型为char *,那么第二行应该是违反约束的行为,至少在latest standard

6.5.16.1简单分配

约束

1以下之一应持有: 112) - 左操作数具有原子,合格或不合格的算术类型,右边有 算术类型;

- 左操作数具有原子,合格或不合格的结构或联合版本 类型与右侧类型兼容;

- 左操作数具有原子,合格或不合格的指针类型,并且(考虑到 两个操作数都是左值操作数在左值转换后的类型 指向兼容类型的限定版或不合格版本的指针,以及指向的类型 左边是所有右边所指类型的限定符;

- 左操作数具有原子,合格或不合格的指针类型,并且(考虑到 左值操作数在左值转换后将具有的类型)一个操作数是一个指针 到对象类型,另一个是指向合格或不合格版本的指针 void,左边指向的类型具有指向的所有类型的限定符 在右边;

- 左操作数是原子的,限定的或不合格的指针,右边是空的 指针常数;或

- 左操作数具有原子,合格或不合格的_Bool类型,右边是a 指针。

或者我错过了什么?