关于malloc和new的几个Tips

1.使用 malloc/calloc 等分配内存的函数时,一定要检查其返回值是否为NULL(亦即检查分配内存的操作是否成功),这是良好的编程习惯,也是编写可靠程序所必需的。
例如DSAA in C中SearchTree Insert函数是是这么写的:

	T = malloc(sizeof(struct TreeNode));
	if (T == NULL)
		FatalError("Out of space!");
	else
		//...

假如malloc分配内存失败,那么返回值为NULL,程序打印一个错误信息并且exit(1),即FatalError,这里的FatalError是一个macro,见随书源码的fatal.h。

malloc分配内存失败的原因有以下两个:
(1)内存不足。
(2)在前面的程序中出现了内存的越界访问,导致malloc()分配函数所涉及的一些信息被破坏。下次再使用malloc()函数申请内存就会失败,返回NULL。
一个例子可以参考malloc函数分配内存失败的原因及解决方法

2.是否要对malloc的返回值进行强制类型转换呢?
假如malloc成功了,那么返回值是一个void指针。而上述代码中的T其实是一个struct TreeNode型指针,这里为什么没有进行强制类型转换呢?
实际上在C语言中void型指针式无需进行转换即可赋给除函数指针外的任何类型指针的,也不推荐进行转换。
而在C++中, 如果不对malloc函数的返回值进行显示的强制类型转换, 则编译会出错,也就是说上述代码应该改为:

	T = (struct TreeNode *) malloc(sizeof(struct TreeNode));

引自函数返回值C语言中malloc函数返回值是否需要类型强制转换问题

所以最好的方法该应是在C言语中malloc函数用不强制类型转换,但如果程序虑考到C++的兼容性的话,那该应应用强制类型转换, 而在C++程序中该应用new来替代malloc分配内存.

关于这个问题,看到一篇不错的文章,可惜源网站已经不能再访问了,看来遇到不错的东西还是记下来比较好:

C/C++ 误区三:强制转换 malloc() 的返回值
来源:蚂蚁的 C/C++ 标准编程 作者:antigloss 等级:精品
发布于2005-10-22 14:17 被读4942次 【字体:大 中 小】
首先要说的是,使用 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§;
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)
本文版权归 蚂蚁的 C/C++ 标准编程 以及 作者 antigloss 共同所有,转载请注明原作者和出处。谢谢。

3.既然提到了C++中应该用new来替代malloc分配内存,那么如何检查new有没有成功呢?
在这里,不应该用上述检查是否是NULL的方法。
参考书:《编写高质量代码:改善C++程序的150个建议》
按照C++标准,如果想检查 new 是否成功,应该捕捉异常。
例如:

    try {  
        int* pStr = new string[SIZE];  
    ...  // processing codes  
    }  
    catch ( const bad_alloc& e ) {  
    return -1;  
    } 

关于malloc和new的更多区别,可以参考这篇文章:
细说new与malloc的10点区别

猜你喜欢

转载自blog.csdn.net/u013213111/article/details/88584316
今日推荐