在反汇编输出(ARM)中,我看到:

    BLX _Znwj


其中BLX是ARM过程调用,而_Znwj则被分解为

$ c++filt  _Znwj
operator new(unsigned int)


operator new是做什么的?它是new还是new[]
它返回什么类型?
如何从C ++中以operator+(a,b)的形式显式调用它?

(我知道这是可能的在类中定义operator new,但这看起来有些不同。)

#1 楼

运行时函数不一定会转换为C ++函数。例如,在没有浮点硬件的处理器上,一个简单的语句,例如
a=b+c;
a,bc处于浮点状态,可能会转换为以bc作为参数的函数调用。并返回结果。用户不应直接调用该函数。
在您的情况下,请考虑每个new可能映射到分配内存并调用构造函数的对象,而每个new[]会为多个元素分配内存并在其上调用构造函数每个元素。 new函数_Znwj函数是new运算符在内部使用的内存分配器(至少在我假设使用gcc的情况下),并且不应直接从C ++中调用它。
此程序:
    class Foo {
            int bar;
    };

    int main(void) {
            Foo *baz=new Foo();
            Foo *var=new Foo[20];
    }

编译为(尝试gcc -S):
    stmfd   sp!, {fp, lr}
    .save {fp, lr}
    .setfp fp, sp, #4
    add     fp, sp, #4
    .pad #8
    sub     sp, sp, #8
    mov     r0, #4                <-- 4 bytes for single variable
    bl      _Znwj
    mov     r3, r0                <-- r0 returns the pointer to the allocated memory
    mov     r2, #0
    str     r2, [r3]
    str     r3, [fp, #-8]
    mov     r0, #80               <-- 80 bytes (20*4) for array
    bl      _Znaj
    mov     r3, r0                <-- r0 returns the pointer to the allocated memory
    str     r3, [fp, #-12]
    mov     r3, #0
    mov     r0, r3
    sub     sp, fp, #4
    @ sp needed
    ldmfd   sp!, {fp, lr}
    bx      lr

因此,您看到的是_Znwj_Znaj是单个类响应的分配器函数。一组类的数组,它们都以所需的字节数作为参数,并且它们都返回一个指向分配的内存的指针作为结果。
回答您的问题:


该运算符new做什么?
它为新的类实例分配内存。


newnew[]吗?
_Znwjnew_Znajnew[]


它返回什么类型?
它返回新分配的存储块的地址。在C ++中,最相似的匹配项是void *,但请注意,它应该指向类结构。


如何从C ++中显式调用它,这在operator+(a,b)中风格?
你不应该那样做。您使用newnew[]。我假设gcc的制造商显式使用了一个函数名称,该名称通常不能从C ++程序调用而不会由于名称冲突而引起语法错误。



评论


实际上,void * x = operator new(4);编译并生成与int * x = new(int)相同的代码;

– 18446744073709551615
2014年5月22日晚上8:57

#2 楼

这称为“ placement new”,并在C ++ 03中引入。它的工作方式是,可以围绕一组硬件寄存器拥有一个C ++类,然后使用放置new将类恰好放在这些硬件寄存器的顶部。例如,如果使用32位控制寄存器,状态寄存器和数据寄存器都从偏移0x50000600开始定义了基于硬件的硬件随机数生成器(RNG),则可以定义一个类:

class RNG_class
{
private:
  volatile uint32_t CR;  // set to 1 to enable
  volatile uint32_t SR;  // low bit set when next num available
  volatile uint32_t DR:
public;
  RNG_class() : CR(1) {} 
  uint32_t next() { while (SR&1 == 0); return DR; }
};


在其他地方,可以将其实例化为

RNG_class RNG* = new(0x50000600) RNG_class();


并且可以将其用作:

r = RNG->next();


有关更多信息,请参阅此问题。