我一直对此很好奇 - 为什么在C++中我必须从malloc
转换返回值,但不在C中?为什么C++需要为malloc()强制转换,但C不是?
这里是C++的作品为例:
int *int_ptr = (int *)malloc(sizeof(int*));
这里是C++中的例子不工作(无施法):
int *int_ptr = malloc(sizeof(int*));
我听说在C,实际上,从malloc()
投射输出是一个错误。
任何人都可以对此主题发表评论吗?
我一直对此很好奇 - 为什么在C++中我必须从malloc
转换返回值,但不在C中?为什么C++需要为malloc()强制转换,但C不是?
这里是C++的作品为例:
int *int_ptr = (int *)malloc(sizeof(int*));
这里是C++中的例子不工作(无施法):
int *int_ptr = malloc(sizeof(int*));
我听说在C,实际上,从malloc()
投射输出是一个错误。
任何人都可以对此主题发表评论吗?
几点:
C允许空指针被隐式转换为任何其它对象指针类型。 C++没有。
将C中的malloc()
的结果放在C中会抑制一个有用的诊断,如果您忘记包含stdlib.h或者没有在范围内具有malloc()
的声明。请记住,如果C在没有事先声明的情况下看到一个函数调用,它将假定该函数返回int
。如果您没有对malloc()
的声明,并且您离开演员表,则会得到一个诊断,表明您试图分配不兼容的类型(int指向指针)。如果你输出了结果,你会抑制诊断并且可能会有运行时问题,因为不能保证将指针值转换为int并返回到指针会给你一个有用的结果。
如果你正在编写C++,你应该使用new
和delete
而不是malloc()
和free()
。是啊,是的,是的,我听说过人们希望他们的代码能够同时编译为C和C++的所有原因,但是使用正确的内存管理工具为语言带来的好处超过维护两个版本IMO的成本。
注:在C89标准中增加了void *
类型; C的早期版本有malloc()
返回char *
,因此在这些版本中,如果您将结果分配给不同的指针类型,则需要铸造为。几乎每个人都至少支持C89标准,所以你遇到这些较早实现的几率非常非常低。
不管任何投射问题,现代编译器都不会输出malloc()缺失声明的警告吗? – 2010-08-13 15:01:36
@Daniel:这也取决于你的警告等级。投射警告通常显示在比缺少声明更低的警告级别。 – 2010-08-13 15:36:52
也许吧,但无论如何离开演员仍然是最好的做法。 – 2010-08-13 15:43:00
C支持从void*
到其他指针类型的隐式转换。 C++不允许它。
的一个原因,它的不赞成在C显式转换的malloc
的返回值是,如果在当前编译单元不包括malloc
签名,编译器将假定返回类型为int
和它的隐式转换根据您指定的指针类型生成编译时警告,并立即解决。在明确演员的情况下,如果你犯了这个错误,将不会发出警告。
这是因为C++是一种强类型语言。在C++中,隐式强制转换只有在“扩展”时才被允许,也就是说,如果新类型可以保存旧类型可以容纳的每个值。允许从较小的整数类型转换为较大的整数类型;从任何指针类型转换到void*
是允许的;允许从子类转换到其超类。所有其他演员必须明确制作,从而告诉编译器“我知道我在做什么,这不是一个错误”。
malloc()
返回一个void*
,它可以是任何东西,所以编译器不能保证你的转换会成功(或有意义)。通过使用明确的转换,你告诉编译器你正在做的事实际上是有意的。
C,OTOH,没有这样严格的铸造规则;你可以高兴地在任何两种类型之间进行投射,而你作为程序员负责确保没有不好的事情发生。
C++更敏感,需要您通过强制类型指定确切类型。 – Abhay 2010-08-13 14:30:56
这不是直接关系到你的问题,但我认为你想'sizeof(int)',而不是'sizeof(int *)'。也就是说,使用'sizeof * int_ptr'会更好,它可以保证为'int_ptr'指向的任何类型分配适当的内存量。 – bcat 2010-08-13 14:31:30
你为什么要在C++中使用malloc? – SoapBox 2010-08-13 14:31:53