operator new []
class X
{
public:
X(){
cout<<"X()"<<endl;
}
X(int x, int y):m_x(x), m_y(y)
{}
private:
int m_x;
int m_y;
};
void * operator new[](size_t n)
{
cout<<"n: "<<n<<endl;
void * ptr = malloc(n);
cout<<"In operator new [] :"<<"ptr = "<<ptr<<endl;
return ptr;
}
X * ptr = new X[2] {X(1, 2), X(3, 4)};
cout<<"After operator new [] :"<<"ptr = "<<ptr<<endl;

- 当
X
未显式定义析构函数,运算符new
传入的n = sizeof(X) * num_elem(元素个数)
, 否则,n = sizeof(X) * num_elem + 4
,多申请的4个字节用于存放X
对象的个数
- 当
X
未显式定义析构函数,malloc
产生的指针地址 = 运算符 new
返回的地址,否则,malloc
产生的指针地址 $\neq$ 运算符 new
返回的地址,operator new [] ()
函数返回后,运算符new
会将该4字节内容赋值为元素的个数
- 上述差异,会导致在new、new[]、delete、delete[]相互对应时产生问题
- 该差异仅取决于其中是否显式定义了
析构函数
- 当自己定义了
void * operator new(size_t n)
而未定义void * operator new[](size_t n)
时,则X * ptr = new X[2]
会调用void * operator new(size_t n)
delete operator & operator delete
- 二者的关系类似于
new operator
与operator new
class X
{
public:
X(){
cout<<"X()"<<endl;
}
X(int x, int y):m_x(x), m_y(y)
{}
~X()
{
}
private:
int m_x;
int m_y;
};
void operator delete(void * ptr)
{
cout<<"In operator delete "<<"ptr = "<<ptr<<endl;
free(ptr);
}
void operator delete [](void * ptr)
{
cout<<"In operator delete []"<<"ptr = "<<ptr<<endl;
free(ptr);
}
X * ptr = new X[2];
delete ptr;
delete ptr;
- 使用
free
进行释放的地址,一定要和malloc
产生的地址值相同,否则会出错
- 当使用
operator new []()
运算符函数分配内存时,使用operator delete []()
函数,进行释放时,此时传入给operator delete []()
函数的地址,即为malloc
分配的地址,因此使用free
进行释放是正确的,当使用运算符delete
释放由new []
产生的内存,并且在X
中显式定义了析构函数时,此时传入operator delete()
中的地址和malloc
分配的地址是不同的,因此会导致free
释放时出错
- 运算符
delete
在释放内存所做的工作:
(1)调用X
的析构函数
(2)将待释放的内存地址传给operator delete()
函数,有它调用free()
函数来进行内存释放工作
- 当使用
delete
释放由new []
分配的内存时,只会调用1次析构函数,然后将该地址原封不动的传入operator delete()
函数,由free()
进行释放,当X
中显式定义了析构函数时,显然free
的地址显然与当初malloc()
产生的地址不同,因此会导致释放出错
- 当使用
delete []
释放new[]
分配的地址时,首先在调用operator delete[]()
函数之前会,查看当前地址前4个字节中存放的元素个数的值nums_elem
,然后调用nums_elem
次析构函数,并将当前地址-4
传入operator delete[]()
函数中,因此此时释放就是正确的
- 同理,当使用
delete []
来释放,由new
产生的内存时,将会导致更大的异常,首先当前地址的前4字节
存的地址是不确定的,因此调用析构函数的次数是不确定的,并且传入给operator delete []()
函数的地址与malloc
产生的地址值也是不同的,因此也会导致释放出错
参考文献
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律