C++ 动态内存管理方式:new 和 delete
我们都知道,在C语言中,通常使用malloc/calloc/realloc/free进行内存管理,这些在C++中可以继续使用,C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理,其主要的优点是,new 不只是分配了内存,它还创建了对象。
为给定变量分配堆内的内存:new
若该变量不需要动态内存时,释放该空间:delete
void Allocate memory()
{
int* ptr1= new int; //动态申请一个int类型空间
int* ptr2=new int(10); //动态申请一个int类型空间并初始化为10
int* ptr3=new int[10]; //动态申请10个int类型空间,数组动态内存分配
delete ptr1; //释放该空间
delete ptr2;
delete[] ptr3; //当申请的是多个空间时,释放时也要释放多个
}
new开辟的空间和malloc开辟出来的一样,都是需要我们用指针指向记录的。
在我们需要开辟几个连续的空间的时候,我们需要用到 new [ ] ,释放空间就要用到 delete [ ] 。
二维数组动态内存分配
int **array;
// 假定数组第一维长度为 m, 第二维长度为 n
// 动态分配空间
array = new int *[m]; //动态开辟m个int*类型的空间
for( int i=0; i<m; i++ )
{
array[i] = new int [n];
}
//释放
for( int i=0; i<m; i++ )
{
delete [] array[i];
}
delete [] array;
对象的动态内存分配
同样的,我们也可以利用new 和 delete 创建多个对象
class T{...};
T* ptr= new T[3]; //同时创建3个T类的对象数组
delete[] ptr;
如果要为一个包含3个 T 对象的数组分配内存,构造函数将被调用3 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(3次)。
new/delete和malloc/free的区别
malloc申请的空间不会初始化,new可以初始化
普通初始化后加(),数组初始化加{}
int* ptr1=new int(2);
int* arr=new int[3]{1,2,3};
malloc和free是函数,new和delete是操作符
malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,
如果是多个对象,[]中指定对象个数即可
int* ptr=(int*)malloc(sizeof(int)*100);
int*ptr2=new int[100];
malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
申请自定义类型对象时,malloc/free不会调用构造函数与析构函数,而new会调用构造函数,delete在释放空间前会调用析构函数
class A
{
public:
A()
{
cout<<"构造函数调用"<<endl;
}
~A()
{
cout<<"析构函数调用"<<endl;
}
private:
int a;
int b;
};
int main()
{
A* a=new A[3];
delete[] a;
return 0;
}

由此可见,使用new和delete为对象动态开辟内存空间,会调用该对象相应的构造函数和析构,可以自动初始化成员变量,释放空间。
malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需
要捕获异常
operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过
operator delete全局函数来释放空间。
// operator new:
// 该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;
// 申请空间失败尝试执行空间不足应对措施,如果用户设置了应对措施,则继续申请,否则抛异常。
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void* p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{
// report no memory
// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
// operator delete:
// 该函数最终是通过free来释放空间的
void operator delete(void* pUserData)
{
_CrtMemBlockHeader* pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); // block other threads
__TRY
// get a pointer to memory block header
pHead = pHdr(pUserData);
// verify block type
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg(pUserData, pHead->nBlockUse); //此处调用free函数
__FINALLY
_munlock(_HEAP_LOCK); // release other threads
__END_TRY_FINALLY
return;
}
// free的实现
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。