C/C++内存分布
new与delete
- 申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]。
- 在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数。
class Test
{
public:
Test(int a = 0) : m_a(a)
{}
~Test()
{}
private:
int m_a;
};
int main()
{
int *p = new int;// 动态申请一个int类型的空间
/*int *p = new int(2); 动态申请一个int类型的空间并赋值*/
delete p;
int *par = new int[10];// 动态申请10个int类型的空间
/*int *par = new int[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 动态申请10个int类型的空间并赋值*/
delete []par;
Test* pt1 = new Test;// 申请单个Test类型的对象
delete pt1;
Test* ptar = new Test[10];// 申请10个Test类型的对象
delete[] ptar;
}
operator new 与operator delete
运算符new和new[]分别调用如下函数,这些函数被称为分配函数,它们位于全局名称空间中。
void *operator new(std::size_t); //use by new
void *operator new[](std::size_t); //use by new[]
同样的,也有由delete和delete[]调用的释放函数:
void operator delete(void *); //use by delete
void operator delete[](void *); //use by delete[]
C++将这些函数称为可替换的。例如,可定义作用于为类的替换函数,并对其进行定制,以满足该类的内存分配。在代码中,仍将使用new运算符,但它将调用您定义的new()函数。
new和delete的实现原理
new的原理
- 调用operator new函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
delete的原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数释放对象的空间
new T[N]的原理
- 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申
请 - 在申请的空间上执行N次构造函数
delete[]的原理
- 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
- 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间
定位new
#include <iostream>
#include <string>
#include <new>
using namespace std;
const int BUF = 512;
class JustTesting
{
private:
string words;
int number;
public:
JustTesting(const string & s = "Just Testing", int n = 0)
{
words = s; number = n; cout << words << " constructed\n";
}
~JustTesting() { cout << words << " destroyed\n"; }
void Show() const { cout << words << ", " << number << endl; }
};
int main()
{
char * buffer = new char[BUF];//使用普通new开辟空间
JustTesting *pc1, *pc2;
pc1 = new (buffer)JustTesting;//把JustTesting定位到buffer上
pc2 = new JustTesting("Heap1", 20); //把JustTesting定位到堆上
cout << "Morery block address:\n" << "buffer: "
<< (void *)buffer << " heap: " << pc2 << endl;
cout << "Memory contest:\n";
cout << pc1 << ": ";
pc1->Show();
cout << pc2 << ": ";
pc2->Show();
JustTesting *pc3, *pc4;
pc3 = new (buffer + sizeof (JustTesting)) JustTesting("Buffer Idea", 10);//确保pc3与pc1地址不重合
pc4 = new JustTesting("Heap2", 10);
cout << "Memory contents:\n";
cout << pc3 << ": ";
pc3->Show();
cout << pc4 << ": ";
pc4->Show();
//使用定位new运算符创建的对象,应以创建顺序相反的顺序删除
//在堆上创建的对象
delete pc2;
delete pc4;
//在buffer上创建的对象不能使用deiete,会释放buffer
pc3->~JustTesting();//显示的调用析构函数
pc1->~JustTesting();
delete[] buffer;
cout << "Done!\n";
system("pause");
return 0;
}