zoukankan      html  css  js  c++  java
  • 从汇编看c++中的placement operator new

    placement operator new是重载的operator new运算符,它允许我们将对象放到一个指定的内存中。下面来看c++源码:

    class X {
    private:
        int _x;
    public:
        X(int xx = 0) : _x(xx) {}
        ~X() {}
        void* operator new(size_t n, void* location) {
            return location;
        }
    };
    
    int main() {
        int i;
        X* xp = new (&i) X;//placement operator new的语法
    };

    下面是main函数里面的汇编码:

    int i;
        14:     X* xp = new (&i) X;
    013913AE  lea         eax,[i]  ;将i的地址给寄存器eax
    013913B1  push        eax  ;压栈eax,作为参数传递给operator new,即传递参数loc
    013913B2  push        4 ;压栈内存大小4,即传递参数size_t 由编译器算出
    013913B4  call        X::operator new (13910FAh) ;调用operator new 
    013913B9  add         esp,8  ;栈顶指针-8,释放调用operator new而传参时分配的栈空间
    013913BC  mov         dword ptr [ebp-0E0h],eax ;eax保存operator new的返回值,即内存空间的首地址
                                                   ;这里是变量i的地址 ,将此地址存入ebp-0E0h所代表的内存
    013913C2  cmp         dword ptr [ebp-0E0h],0  ;将ebp-0E0h内存里面的值与0做比较,判断是否为空指针
    013913C9  je          main+50h (13913E0h) ;如果为空,就跳转到地址13913E0h处执行,否则,顺序执行
                                              ;这里顺序执行 
    013913CB  push        0  ;压入参数0,为调用构造函数传递参数
    013913CD  mov         ecx,dword ptr [ebp-0E0h] ;将 ebp-0E0h内存中的值(变量i的地址)给寄存器ecx
                                                    ;作为隐含参数(即this指针)传递给构造函数
    013913D3  call        X::X (1391041h);调用构造函数  
    013913D8  mov         dword ptr [ebp-0E8h],eax  ;寄存器eax存有对象首地址(即变量i的地址),将eax的值给ebp-0E8h所代表的内存
    013913DE  jmp         main+5Ah (13913EAh)  ;跳转到地址13913EAh处执行
    013913E0  mov         dword ptr [ebp-0E8h],0  ;这一条指令是013913C2 处判断失败后将要执行的指令
                                                  ;将0给ebp-0E8h所代表的内存
    013913EA  mov         ecx,dword ptr [ebp-0E8h]  ;将ebp-0E8h内存的值给寄存器ecx
    013913F0  mov         dword ptr [xp],ecx  ;ecx的值(对象首地址)给指针变量xp
        15: };

    从汇编码可以看到,首先调用重载之后的placement operator new运算符,它仅仅返回的是变量i的地址。接下来,编译器将这个地址作为所要构造对象的首地址,作为this指针传给了构造函数,进行构造函数的调用。最后,将对象首地址(也就是变量i的地址)给了指针变量xp,从而在变量i处的内存中构造了一个对象。

    需要注意的是如果类X所占用的内存比一个int i大,那么,在这种情况下构造的时候,将引起程序崩溃。

  • 相关阅读:
    一个简单的makefile,一次性编译本文件夹下所有的cpp文件
    c++ 最短路两种算法
    C++语言十进制数,CDecimal(未完成)
    C语言面向对象的简便方法
    C语言2048
    C图书借还示例
    Javascript 备忘
    原型与原型链
    css3动画-跳动圈
    学习css3动画
  • 原文地址:https://www.cnblogs.com/chaoguo1234/p/3220293.html
Copyright © 2011-2022 走看看