C语言中
使用:malloc/calloc/realloc/free 进行动态内存管理
calloc:分配n个长度为size的连续内存空间,并初始为0
realloc:重新分配空间
void* realloc(void* p,size_t size)
p为指向之前分配的内存块的指针
int*p1=(int*)malloc(sizeof(int)*4);
int*p2=(int*)calloc(4,sizeof(int));
int*p3=(int*)realloc(p2,sizeof(int)*6);
free(p1);
//p2不需要释放,否则会重复释放
free(p3);
注意点:
C++中
使用:new/delete
new[ ]/delete[ ] 进行动态内存管理
int* p4=new int;//动态分配4个字节(int)
int* p5=new int(2);//动态分配4个字节,并初始化为2
int* p6=new int[2];//动态分配8个字节(2*4),2为对象个数
delete p4;
delete p5;
delete p6[];
深入理解动态内存管理
一、malloc/free和new/delete的区别和联系
- 都是用来动态管理内存的
- malloc/free是c语言中的;new/delete是c++中的
- malloc/free只分配/释放空间;
new/delete因为是在c++中才有的(c++中有类的概念),所以除了分配空间还会调用构造函数和析构函数进行初始化与清理 - new/deiete会自己计算类型的大小,返回对应类型的指针
探究new/delete
这里要提到operator new和operator delete函数,这是两个标准库函数。这两个函数没有重载new和delete。
按F11调试,我们会发现new其实调用了operator new函数
operator new与new
operator new与malloc用法一样
operator new只负责分配空间,不会调用对象的构造函数,
实际上operator new/operator delete只是malloc/free的一层封装
总结:
new做了两件事
- 调用operator new分配空间
- 调用构造函数初始化对象
new[N]
- 调用operator new分配空间
- 调用N次构造函数分别初始化每个对象
delete同理
定位new表达式
new的定位表达式是在已分配的原始内存空间中调用构造函数构造对象
优点:创建对象但是不分配内存,而是在已有的内存块上面创建对象。用于需要反复创建并删除的对象,可以降低分配释放内存的性能消耗。 就是一次把内存给够,不要老是向操作系统要内存
new (place_address) type
new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表。
1.malloc/free + 定位操作符new()/显示调用析构函数,模拟 new和delete 的行为
2.malloc/free + 多次调用定位操作符new()/显示调用析构函数,模拟 new[]和delete[] 的行为
使用起来,简单来说就四部
AA*p1=(AA*)operator new(sizeof(AA));//开空间
new(p1)AA;//构造对象
p1->~AA();//销毁对象
operator delete(p1);释放掉空间,还回系统
如何使用?
class AA
{
public:
AA(int a = 0,int b=0)
:_a(a)
,_b(b)
{}
void Show()
{
cout <<_a<<"->"<<_b<<endl;
}
~AA()
{
cout << "~AA()"<< endl;
}
private:
int _a;
int _b;
};
int main()
{
//1、开辟空间,一个大的内存池,将空间一次给够
//两种开辟方式:
AA* p = (AA*)malloc(sizeof(AA)* 3);
//AA* p=(AA*)operator new(sizeof(AA)*3);
//用刚才开辟的空间
AA* pb1 = new (p)AA(0,1);
pb1->Show(); //0->1
pb1->~AA();//调析构,销毁对象,但不会释放内存
AA* pb2 = new (p+1)AA(1,2);
pb2->Show(); //1->2
pb2->~AA();
AA* pb3 = new (p+ 2)AA(2,3);
pb3->Show(); //2->3
pb3->~AA();
free(p);
//operator delete(p);//使用完空间成后手动释放空间
system("pause");
return 0;
}