回 帖 发 新 帖 刷新版面

主题:[转帖]C/C++ 误区三:强制转换 malloc() 的返回值

C/C++ 误区三:强制转换 malloc() 的返回值
作者:antigloss 

    首先要说的是,使用 malloc 函数,请包含 stdlib.h(C++ 中是 cstdlib),而不是 malloc.h 。因为 malloc.h 从来没有在 C 或者 C++ 标准中出现过!因此并非所有编译器都有 malloc.h 这个头文件。但是所有的 C 编译器都应该有 stdlib.h 这个头文件。

    在 C++ 中,强制转换 malloc() 的返回值是必须的,否则不能通过编译。但是在 C 中,这种强制转换却是多余的,并且不利于代码维护。

    起初,C 没有 void 指针,那时 char* 被用来作为泛型指针(generic pointer),所以那时 malloc 的返回值是 char* 。因此,那时必须强制转换 malloc 的返回值。后来,ANSI C(即C89) 标准定义了void 指针作为新的泛型指针。void 指针可以不经转换,直接赋值给任何类型的指针(函数指针除外)。从此,malloc 的返回值变成了 void* ,再也不需要强制转换 malloc 的返回值了。以下程序在 VC6 编译无误通过。

        #include <stdlib.h>
        int main( void )
        {
            double *p = malloc( sizeof *p ); /* 不推荐用 sizeof( double ) */
            free(p);
            return 0;
        }

    当然,强制转换malloc的返回值并没有错,但画蛇添足!例如,日后你有可能把double *p改成int *p。这时,你就要把所有相关的 (double *) malloc (sizeof(double))改成(int *)malloc(sizeof(int))。如果改漏了,那么你的程序就存在 bug 。就算你有把握把所有相关的语句都改掉,但这种无聊乏味的工作你不会喜欢吧!不使用强制转换可以避免这样的问题,而且书写简便,何乐而不为呢?使用以下代码,无论以后指针改成什么类型,都不用作任何修改。

        double *p = malloc( sizeof *p );

    类似地,使用 calloc ,realloc 等返回值为 void* 的函数时,也不需要强制转换返回值。

参考资料:
ISO/IEC 9899:1999 (E) Programming languages — C 7.20.3.3 The malloc function
ISO/IEC 9899:1999 (E) Programming languages — C P104 (6.7.2.2)

回复列表 (共14个回复)

沙发

C++中就不应该使用malloc.还要有节制的使用new[].

板凳

[quote]
以下程序在 VC6 编译无误通过。

        #include <stdlib.h>
        int main( void )
        {
            double *p = malloc( sizeof *p ); /* 不推荐用 sizeof( double ) */
            free(p);
            return 0;
        }
[/quote]

楼主,这是哪来的文章?我的vc6难道与众不同?
error C2440: 'initializing' : cannot convert from 'void *' to 'double *'


//to 4楼sarrow,是我没看仔细。3Q~

3 楼

good, good, very very good.

4 楼

2cracker007:


这是1:

[quote]在 C++ 中,强制转换 malloc() 的返回值是必须的,否则不能通过编译。但是在 C 中,这种强制转换却是多余的,并且不利于代码维护。[/quote]


这是2:

VC只是一个IDE而已!编译的时候,是通过命令行参数告诉编译器应该用什么标准编译当前代码 -- 默认的行为是对.c后缀使用C标准,对.cpp后缀使用C++标准....

5 楼

6 楼

上次看了格子回的那个贴子
说在CSDN上看见有人建议尽量不用强制类型转换
我想了想是不是这个样子

有两个理由
1。如果精度高转换为精度低的那样会丢失精度
2。如果精度低转为精度高的那样会浪费存储空间

7 楼

但是在 C 中,这种强制转换却是多余的,并且不利于代码维护。
---------------------------------------------------------
恰恰相反,在c中使用强制转换有利于代码的维护。虽然c支持把void指针赋予一个普通指针(这是c与c++的区别之一),但在malloc前加上强制转换这种行为是作为一个良好风格而存在的,利于日后当需要把代码向c++移植时,不需要再加上强制转换。

8 楼

[quote]
恰恰相反,在c中使用强制转换有利于代码的维护。虽然c支持把void指针赋予一个普通指针(这是c与c++的区别之一),但在malloc前加上强制转换这种行为是作为一个良好风格而存在的,利于日后当需要把代码向c++移植时,不需要再加上强制转换。
[/quote]

这种东西可以看作是写作风格 -- 和你喜欢用行注释还是块注释一样,这些东西都很容易修改的!并不会给移植性带来多大的麻烦!

9 楼

To tell you the truth:

Please don't read some series such as "C/C++ 误区二" "C/C++ 误区三" etc

Those people think he/she knows a lot and start to write series to teach others, most of them (not all of them) are misleading!!!!

The samething happens in other Java forums too, someone almost know nothing about Java, started to write "classic 误区 in Java..."

I decided not to read those garbage, just in case I want to criticize again...

But I found C语言爱好者 started to comment, that made me come here...

10 楼

I don't know why our moderators are so cheap, when they see something in 1,  2, 3 series, immediately added as "精华贴 ". Made garbage permanently misleading beginners....

Sigh!!!!!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册