malloc与new差异

一、mallloc/free 与 new/delete 分配内存差异

1、malloc 是C/C++ 标准库函数; new是C++运算符,同“+-*/”一样。
2、new 分配的是对象,会调用对象的构造函数;malloc 仅分配内存。(操作对象不同)
3、操作差异。
    malloc 函数原型:
    void * malloc (size_t size);
    返回的是 void * 类型,若使用它必须主动进行类型转换。
     char* pchr;
     //pchr = malloc( sizeof(char) * MAX); //编译不通过
    pchr = (char*)malloc( sizeof(char) * MAX);//正确
    free 函数原型:
    void free(void* memblock);
    free释放malloc分配的空间会成功(因事先知道内存大小),若释放之后未置空,再次free则将导致运行出错。free(NULL)则是能正常进行操作。
    new 则不需要指定类型。
4、注意 delete 和 free 之后都要将 指针赋空值。漏掉这种操作是导致程序出现野指针的主要原因。

ps:某次看到用 malloc/free 无法满足非内部数据类 动态对象的要求(即自定义类),实际上 placement new 能达到类似的要求,类似于主动调用构造函数。即可先用 malloc 分配地址,然后在起始地址处调用构造函数,不使用对象之后,主动调用 析构函数,如果析构函数中未把申请的动态内存释放完毕, 则需要再调用 free 函数。

二、new,operator new,placement new 说明
new:不能被重载,它先调用 Operator new 分配内存,然后调用构造函数初始化这段内存。
operator new:类似于 operator +/operate -这种。若要实现不同的内存分配行为,应重载operator new,而不是 new。operator delete与delete 类似。delete 首先调用对象的析构函数,然后才调用 operator delete 释放内存。
placement new:operator new 重载的一个版本。本身不分配内存,仅返回指向已分配好的某段内存的一个指针。因此不能删除它,但要调用对象的析构函数。使用placement new 需要添加 #include<new> 

placement new 存在的意义:
new 分配数组时,调用默认构造函数,效率不佳,若没有默认构造函数,则发生编译错误。placement new允许在已非配的内存上创建对象;效率高,new操作需要在堆中查找空间,操作速度较慢,且可能出现无法分配的情况,placement 不需要查找内存,适合对时间要求较高,且长时间运行不希望被打断的应用程序。
placement 使用过程:
1、提前分配缓存:①用new、malloc在堆上分配空间;②在栈上分配空间,临时变量;③直接地址
2、对象分配。由1操作获得执行地址的指针 buf,这一步调用 placement new 构造对象:
Obj *pobj = new(buf) Obj;//相当于主动调用类构造函数;
3、使用。像普通对象指针使用 pobj 。
4、对象析构,需要主动调用析构函数:pobj->~Obj();
5、如果是堆区分配的内存,则需要主动释放它:delete/free 等。


三、delete 与 delete[] 注意
delete NULL / delete[] NULL 是可执行通过的。
同时对于内部数据类型,因为不涉及构造函数和析构函数的调用,delete 与 delete [] 操作通用,似乎没有差别;但是对于自定义类型,需要调用构造函数及析构函数时,则需要严格按照 new/delete, new[]/delete[]对应操作来进行。此处有一解释:http://www.360doc.com/content/10/1118/15/1579921_70434158.shtml 。

最后附上一段源码:
代码中最后一段是个测试类大小的Demo,顺便复习一下C++类存储
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <malloc.h>
#include <vld.h>
#include <new>

class CT{
	char a;
public:
	CT(){
		printf_s("Constructor!\n");
	}
	~CT(){
		printf_s("Deconstructor!\n");
	}
};
class CVir{
public:
	virtual ~CVir();
};
class CIn:public CT,public CVir
{
};
int main()
{
	const int MAX = 100;
	char mystring[MAX]="Hello my Sweet";

	char* pchr;
	pchr = (char*)malloc( sizeof(char) * MAX);	//编译失败
	if ( !pchr )
		printf( "malloc failed\n" );
	else
	{
		printf_s("pchr=0x%08x\n", (long)pchr);
		strcpy_s(pchr, sizeof(mystring), mystring); 
		printf_s("%s\n", pchr);
		free(pchr);
		printf_s("After free!\n");
		printf_s("pchr=0x%08x\n", (long)pchr);
		pchr =NULL;
	}

	printf_s("\nBeforeNew pchr=0x%08x\n", (long)pchr);
	pchr = new char[MAX];
	if (!pchr)
		printf( "New failed!\n" );
	else
	{
		printf_s("\np2chr=0x%08x\n", (long)pchr);
		strcpy_s(pchr, sizeof(mystring), mystring); 
		printf_s("%s\n", pchr);
		delete [] pchr;
		printf_s("After delete[]!\n");
		printf_s("p2chr=0x%08x\n", (long)pchr);
		pchr =NULL;
		delete [] pchr;
		printf_s("p2chr=0x%08x\n", (long)pchr);
	}

	printf_s("\nCT数组分配:\n");
	const int Num = 2; 
	CT* pct = new CT[Num];	
	//delete pct;		//错误,编译通过,执行失败
	delete []pct;			//正确

	printf_s("\nCT单元素分配:\n");
	pct =new CT;
	//delete[] pct;	//错误,编译通过,执行失败
	delete pct;		//正确

	printf_s("\ndelete char数组\n");
	pchr = new char[MAX];
	delete pchr;
	pchr =NULL;

	printf_s("\ndelte [] char单元素\n");
	pchr = new char;
	delete [] pchr;

	printf_s("\nPlacement New 演示\n");
	printf_s("CT对象大小:%d\n", sizeof(CT));
	char* buff[ sizeof(CT) ];
	pct = new(buff) CT ;
	pct->~CT();

	printf_s("CVir对象大小:%d, CIn 对象大小:%d\n", sizeof(CVir), sizeof(CIn));
	return 1;
}
运行结果:


完毕



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值