malloc与new差异

来源:互联网 发布:strikingly 用 建站 编辑:程序博客网 时间:2024/05/16 06:43
一、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;}
运行结果:


完毕



0 0
原创粉丝点击