zoukankan      html  css  js  c++  java
  • 重载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

  • 相关阅读:
    ansible变量
    nginx连接php测试
    redis发布订阅
    堡垒机实例以及数据库操作
    nginx简介,使用
    protobuf
    go NSQ
    go mod
    GIT版本管理工具教程
    linux命令查询网站
  • 原文地址:https://www.cnblogs.com/fangkm/p/1635357.html
Copyright © 2011-2022 走看看