我在这个帖子上对我的回答发表了评论:
函数调用中的malloc似乎在返回时被释放?
总之,我有这样的代码:
int * somefunc (void) { int * temp = (int*) malloc (sizeof (int)); temp[0] = 0; return temp; }
我有这个评论:
我可以说,请不要转换malloc的返回值?它不是必需的,可以隐藏错误.
我同意在C中不需要强制转换.它在C++中是强制性的,所以我通常添加它们以防万一我必须在C++中移植代码.
但是,我想知道这样的演员是如何隐藏错误的.有任何想法吗?
编辑:似乎双方都有非常好的和有效的论据.感谢发帖,伙计们.
我发布一个答案似乎很合适,因为我留下了评论:P
基本上,如果你忘记包含stdlib.h
编译器将假设malloc
返回一个int
.没有施法,你会收到警告.铸造你不会.
因此,通过施放你什么也得不到,并冒着压制合法警告的风险.
关于这一点很多,快速谷歌搜索将提出更详细的解释.
有人认为
TYPE * p; p = (TYPE *)malloc(n*sizeof(TYPE));
使它明显,当你不小心,因为比方说,你想过没有分配足够的内存p
是TYPe
没有TYPE
,因此,我们应该投malloc的,因为这种方法的优点是覆盖的意外抑制编译器警告较小的成本.
我想指出两件事:
你应该写信p = malloc(sizeof(*p)*n);
总是确保malloc适当的空间
如果你改变了类型,你需要在3个地方进行更改p
:一次在声明中,一次在转换中malloc
,一次在转换中.
简而言之,我个人认为没有必要投出回报价值,malloc
这当然不是最佳做法.
这个问题被标记为C和C++,所以它至少有两个答案,恕我直言:
C咳咳......做你想做的事.
我相信上面给出的理由"如果你不包括"stdlib"那么你就不会得到警告"不是一个有效的,因为我不应该依赖这种黑客来忘记包含一个标题.
可能使你不能编写演员表的真正原因是C编译器已经默默地将一个void *
指针类型转换为你想要的任何指针类型,因此,自己动手做是有点过分和无用的.
如果你想要类型安全,你可以切换到C++或编写自己的包装函数,如:
int * malloc_Int(size_t p_iSize) /* number of ints wanted */ { return malloc(sizeof(int) * p_iSize) ; }C++
有时,即使在C++中,您也必须从malloc/realloc/free utils中获利.然后你将不得不施展.但你已经知道了.与往常一样,使用static_cast <>()将比C风格的强制转换更好.
在C中,您可以通过模板覆盖malloc(和realloc等)以实现类型安全:
templateT * myMalloc(const size_t p_iSize) { return static_cast (malloc(sizeof(T) * p_iSize)) ; }
将使用如下:
int * p = myMalloc(25) ; free(p) ; MyStruct * p2 = myMalloc (12) ; free(p2) ;
和以下代码:
// error: cannot convert ‘int*’ to ‘short int*’ in initialization short * p = myMalloc(25) ; free(p) ;
不会编译,所以,没有问题.
总而言之,在纯C++中,如果有人在您的代码中找到多个C malloc,您现在没有任何借口...... :-)
C + C++交叉有时,您希望生成可以在C和C++中编译的代码(无论出于何种原因......这不是C++ extern "C" {}
块的重点吗?).在这种情况下,C++需要强制转换,但C不会理解static_cast关键字,所以解决方案是C风格的强制转换(由于这种原因,它在C++中仍然是合法的).
请注意,即使编写纯C代码,使用C++编译器进行编译也会获得更多警告和错误(例如,尝试使用函数而不首先声明它将无法编译,这与上面提到的错误不同).
因此,为了安全起见,编写将在C++中干净地编译的代码,研究并更正警告,然后使用C编译器生成最终的二进制文件.这意味着再次以C风格的演员表演.
它可能引入的一个可能的错误是,如果您使用C(而不是C++)在64位系统上进行编译.
基本上,如果您忘记包含stdlib.h
,则将应用默认的int规则.因此编译器很乐意假设malloc
具有int malloc();
On Many 64位系统的原型,int为32位,指针为64位.
哦,哦,值被截断,你只得到指针的低32位!现在,如果您转换返回值malloc
,则此错误将被强制转换隐藏.但是如果你不这样做,你会得到一个错误("无法将int转换为T*"的性质).
当然,这不适用于C++有两个原因.首先,它没有默认的int规则,其次它需要强制转换.
总而言之,你应该只使用c ++代码中的新东西:-P.
嗯,我认为这恰恰相反 - 总是直接将其转换为所需的类型.请继续阅读!