当前位置:  开发笔记 > 编程语言 > 正文

在C中不必要的指针转换

如何解决《在C中不必要的指针转换》经验,为你挑选了4个好方法。

我在这个帖子上对我的回答发表了评论:

函数调用中的malloc似乎在返回时被释放?

总之,我有这样的代码:

int * somefunc (void)
{
  int * temp = (int*) malloc (sizeof (int));
  temp[0] = 0;
  return temp;
}

我有这个评论:

我可以说,请不要转换malloc的返回值?它不是必需的,可以隐藏错误.

我同意在C中不需要强制转换.它在C++中是强制性的,所以我通常添加它们以防万一我必须在C++中移植代码.

但是,我想知道这样的演员是如何隐藏错误的.有任何想法吗?

编辑:

似乎双方都有非常好的和有效的论据.感谢发帖,伙计们.



1> freespace..:

我发布一个答案似乎很合适,因为我留下了评论:P

基本上,如果你忘记包含stdlib.h编译器将假设malloc返回一个int.没有施法,你会收到警告.铸造你不会.

因此,通过施放你什么也得不到,并冒着压制合法警告的风险.

关于这一点很多,快速谷歌搜索将提出更详细的解释.

编辑

有人认为

TYPE * p;
p = (TYPE *)malloc(n*sizeof(TYPE));

使它明显,当你不小心,因为比方说,你想过没有分配足够的内存pTYPe没有TYPE,因此,我们应该投malloc的,因为这种方法的优点是覆盖的意外抑制编译器警告较小的成本.

我想指出两件事:

    你应该写信p = malloc(sizeof(*p)*n);总是确保malloc适当的空间

    如果你改变了类型,你需要在3个地方进行更改p:一次在声明中,一次在转换中malloc,一次在转换中.

简而言之,我个人认为没有必要投出回报价值,malloc这当然不是最佳做法.



2> paercebal..:

这个问题被标记为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等)以实现类型安全:

template 
T * 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风格的演员表演.



3> Evan Teran..:

它可能引入的一个可能的错误是,如果您使用C(而不是C++)在64位系统上进行编译.

基本上,如果您忘记包含stdlib.h,则将应用默认的int规则.因此编译器很乐意假设malloc具有int malloc();On Many 64位系统的原型,int为32位,指针为64位.

哦,哦,值被截断,你只得到指针的低32位!现在,如果您转换返回值malloc,则此错误将被强制转换隐藏.但是如果你不这样做,你会得到一个错误("无法将int转换为T*"的性质).

当然,这不适用于C++有两个原因.首先,它没有默认的int规则,其次它需要强制转换.

总而言之,你应该只使用c ++代码中的新东西:-P.



4> unexist..:

嗯,我认为这恰恰相反 - 总是直接将其转换为所需的类型.请继续阅读!


经过一番思考之后,那篇文章所提出的论点并不是很好.你应该简单地使用p = malloc(sizeof(*p)*n); 一起避免这个问题.现在你不必在3个地方改变类型:一次在声明p,一次在malloc,一次在演员表中.
推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有