技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 625|回复: 0
收起左侧

【C】经典问题:我用malloc分配内存给数组的时候,是不是应该把返回值转换成对应的类型?

[复制链接]

985

主题

2162

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15934 个
贡献
30898 次
宅之契约
0 份
在线时间
1514 小时
注册时间
2014-1-26
发表于 2017-1-5 06:08:56 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
标题有点长,我换句话描述一下就是:

int *array = (int*)malloc(50 * sizeof *array);
int *array = malloc(50 * sizeof *array);
这两句是上面好还是下面好?

VS党一般都会说,肯定是上面好,而GCC党则认为下面好。

首先我先说明一下,这两条语句到底有啥区别:
第二句不能在C++里编译通过,它是C语言的语句,因为C语言的void*可以转换成任何类型,C++则不支持这样的转换。
因此对于C语言而言,这种转换是多余的。
第一句有个强制类型转换,也就是说无论malloc的返回类型是什么,它都会试图将其转换为int*。
这里重点说一下,为什么要注意这个。

1、malloc是C标准库的函数,理论上是跨平台的,但不是所有的平台都在stdlib.h里面声明了它的原型。
你可以说“我用malloc.h”,这是个好主意,多数平台都有这个头文件,而且它里面一定会有malloc函数的声明。
有的平台没有在stdlib.h里声明malloc函数,这会导致malloc被临时定义为一个返回int类型的函数。
一旦malloc的返回值类型是int,而你的代码被编译到了64位的环境,如果你没有强制类型转换,编译器就会认为这个函数返回的不是int,而是一个指针。而如果你写了强制类型转换,编译器就会认为“你是故意把一个32位返回值赋值给64位指针变量的”,于是,它就在没有任何提示的情况下,把malloc的返回值的低32位部分赋值给了你的变量,隐藏了一个BUG(估计很多开发者在遇到崩溃、找这个BUG的时候都得吐血!)

2、这种情况很少在VS党身上发生,因为VS的智能提示功能是针对C++的,就算你写的是用C编译器编译的、后缀是.c的彻彻底底的C语言文件,VS也会用C++的智能提示在你的代码上画上难看的红色波浪线,提示你“无法将void*类型转换为int*类型”,即使你能成功编译它,即使编译器本身并不会给你任何警告。
但要知道开发者们有谁没有强迫症呢,于是VS党们都会老老实实地进行强制类型转换(然后在写跨平台x64的时候经历一次挫折,哈哈哈哈哈哈哈)
关键是,VS的malloc.h和stdlib.h里都有malloc的声明,并且都是返回void*的。不跨平台的话,万事大吉,这是不是也说明VS阻碍了跨平台开发呢?

总结一下,在跨平台开发的时候,你如果能保证你的源码里一定会有正确的malloc函数的声明,或者,你希望你的代码能够通过C++的编译,那么,请用强制类型转换。否则,直接把malloc的返回值不经过任何转换传递给你的指针变量,才是明智之举,即使VS强行给你打上丑陋的波浪线!

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-5-24 04:36 , Processed in 0.078620 second(s), 14 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表