重载new和delete操作符

以前没重载过操作符new和delete,最近由于项目需要,写了个试试.本以为手到擒来,没想到还遇到不少问题.

class  CTestNew
{
public:
    CTestNew()
    {
        AtlTrace(_T(
"CTestNew\n"));
    }

    
~CTestNew()
    {
        AtlTrace(_T(
"~CTestNew\n"));
    }

    
void* operator new (size_t size)
    {
        AtlTrace(_T(
"operator new\n"));
        
void* p = malloc(size);
        
return p;
    }

    
void operator delete (void* p)
    {
        AtlTrace(_T(
"operator delete\n"));
        free(p);
    }
};

当调用如下代码:

CTestNew *= new CTestNew;
delete p;

其输出是:

operator new
CTestNew
~CTestNew
operator delete

这都没发现什么问题.但是我平时写代码一般先不写实现,直接返回NULL的。于是问题出来了.修改一下new的重载代码:

    void* operator new (size_t size)
    {
        AtlTrace(_T("operator new\n"));
        return NULL;
    }

再次调用时只输出:operator new

构造函数、析构函数、operator delete函数都没调用。出乎我意料之外。

反汇编跟踪了一下:

//当调用operator new 函数时,其把函数的返回值保存在eax寄存器中

0043A794  call        CTestNew::operator new (4367DAh)
0043A799  add         esp,4
0043A79C  mov         dword ptr [ebp-104h],eax
0043A7A2  mov         dword ptr [ebp-4],0

//与0做比较  如果相等 就跳转到0043A7C5处,因此跳过了执行构造函数CTestNew
0043A7A9  cmp         dword ptr [ebp-104h],0
0043A7B0  je          CMainDlg::OnOK+75h (43A7C5h)
0043A7B2  mov         ecx,dword ptr [ebp-104h]

//执行构造函数
0043A7B8  call        CTestNew::CTestNew (436672h)
0043A7BD  mov         dword ptr [ebp-118h],eax
0043A7C3  jmp         CMainDlg::OnOK+7Fh (43A7CFh)
0043A7C5  mov         dword ptr [ebp-118h],0
0043A7CF  mov         eax,dword ptr [ebp-118h]
0043A7D5  mov         dword ptr [ebp-110h],eax
0043A7DB  mov         dword ptr [ebp-4],0FFFFFFFFh
0043A7E2  mov         ecx,dword ptr [ebp-110h]
0043A7E8  mov         dword ptr [ebp-20h],ecx
        delete p;
0043A7EB  mov         eax,dword ptr [ebp-20h]
0043A7EE  mov         dword ptr [ebp-0ECh],eax
0043A7F4  mov         ecx,dword ptr [ebp-0ECh]
0043A7FA  mov         dword ptr [ebp-0F8h],ecx

//一路跟踪  此时ebp-0F8h地址处的值正是operator new 函数的返回值

//与0做比较  如果相等 就跳转到0043A81E处,因此跳过了执行析构函数~CTestNew和operator delete函数
0043A800  cmp         dword ptr [ebp-0F8h],0
0043A807  je          CMainDlg::OnOK+0CEh (43A81Eh)
0043A809  push        1   
0043A80B  mov         ecx,dword ptr [ebp-0F8h]
0043A811  call        CTestNew::`scalar deleting destructor' (437770h)
0043A816  mov         dword ptr [ebp-118h],eax
0043A81C  jmp         CMainDlg::OnOK+0D8h (43A828h)
0043A81E  mov         dword ptr [ebp-118h],0

原文地址:https://www.cnblogs.com/fangkm/p/1635357.html