目录
2.C语言中内存管理的方式:malloc/calloc/realloc/free
4.operator new和operator delete 函数
1.C/C++内存分布
2.C语言中内存管理的方式:malloc/calloc/realloc/free
3.C++内存管理方式
在C++中可以继续用C语言内存管理那一套,但有的时候就无能为力了。而且使用起来比较麻烦,所以C++又提出了新的内存管理方式:通过new和delete操作符进行内存管理
3.1 new和delete操作内置类型
int main()
{
int* p1 = new int;//使用new动态申请一个int整型字节的空间
int* p2 = new int(10);//动态申请1个int整型字节的空间并初始化为10
int* p3 = new int[5];//动态申请五个int整型字节的空间
delete p1; //释放p1申请的空间
delete p2; //释放p2申请的空间
delete[] p3; //释放p3申请的空间
return 0;
}
//注意:申请和释放单个元素使用new/delete,申请和释放多个元素的空间使用new[]/delete[]。配套使用
3.2 new和delete操作自定义类型
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(构造)" << this << endl;
}
~A()
{
cout << "~A(析构)" << this << endl;
}
A(const A& a)
{
cout << "A(拷贝构造)" << this << endl;
_a = a._a;
}
private:
int _a;
};
int main()
{
A* a1 = new A(5);//new动态开辟一个A类型对象的空间,调用一次构造函数初始化为5
A* a2 = new A[3];//new动态开辟三个A类型对象的空间,调用三次构造函数
//C++98不支持new开辟连续空间后初始化,C++11支持连续初始化
delete a1; //delete释放,调用一次析构
delete[] a2; //delete释放,调用三次析构
return 0;
}
通过运行代码可以发现new和delete与malloc和free的第一个区别就是new/delete会自动调用自定义类型对象的构造和析构函数。而malloc和free则不会。
4.operator new和operator delete 函数
4.1 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 ); __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来释放空间的。
5.new和delete的实现原理
5.1 内置类型
内置类型new/delete和malloc/free基本相似,不过new/delete申请的是单个字节的空间,而new[]/delete[]申请的是连续的空间。还有就是malloc申请失败返回空指针,而new/new[]申请失败抛异常。
5.2 自定义类型
new的原理:
1.申请内存空间时调用operator new全局函数。
2.在申请的空间上调用构造函数,完成对象构造
delete的原理:
1.在申请的空间上调用析构函数,完成对象的清理工作
2.调用operator delete全局函数释放对象的空间。
new T[N]的原理
1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对
象空间的申请
2. 在申请的空间上执行N次构造函数
delete[]的原理
1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释
放空间