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

这两条线有什么区别?

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

4

4 回答 4

5

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

第二次强制转换将 malloc 返回的指针转换为单个字符。这很糟糕,原因有很多:

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

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

于 2013-03-27T22:50:06.960 回答
2

第二行是错误的(转换为 achar会将指针截断为仅一个字节,使数据tmpString包含无效地址),但 C 中的所有转换都未经检查,因此您永远不会对它们产生错误。

于 2013-03-27T22:46:52.807 回答
2

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

于 2013-03-27T22:47:08.490 回答
0

假设tmpString有 type char *,那么第二行应该是违反约束的,至少在最新的标准下:

6.5.16.1 简单赋值

约束

1 应满足以下条件之一:112) — 左操作数具有原子、合格或不合格算术类型,而右操作数具有算术类型;

— 左操作数具有与右操作数兼容的结构或联合类型的原子、限定或非限定版本;

左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且 left 指向的类型具有right 指向的类型的所有限定符;

左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个是指向的限定或非限定版本的指针void,并且left指向的类型具有right指向的类型的所有限定符;

— 左操作数是原子的、限定的或非限定的指针,右操作数是空指针常量;或

— 左操作数的类型为 atomic、qualiified 或 unqualiified _Bool,而右操作数是指针。

还是我错过了什么?

于 2013-03-27T23:33:08.577 回答