在反汇编器输出(ARM)中,我看到:
BLX _Znwj
哪里BLX是 ARM 过程调用并被_Znwj分解为
$ c++filt _Znwj
operator new(unsigned int)
那有什么作用operator new?是new还是new[]?它返回什么类型?我如何从 C++ 中显式调用它,某种operator+(a,b)风格?
(我知道可以operator new在类中定义,但这看起来有点不同。)
在反汇编器输出(ARM)中,我看到:
BLX _Znwj
哪里BLX是 ARM 过程调用并被_Znwj分解为
$ c++filt _Znwj
operator new(unsigned int)
那有什么作用operator new?是new还是new[]?它返回什么类型?我如何从 C++ 中显式调用它,某种operator+(a,b)风格?
(我知道可以operator new在类中定义,但这看起来有点不同。)
运行时函数不一定转换为 C++ 函数。例如,在没有浮点硬件的处理器上,像这样的简单语句
a=b+c;
用a,b并且c被浮动,可能会被转换为函数调用需要b和c作为参数并返回结果。用户不应直接调用该函数。
在您的情况下,请考虑每个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做什么的?
它为新的类实例分配内存。
是new还是new[]?
_Znwj是new,并且_Znaj是new[]。
它返回什么类型?
它返回新分配的内存块的地址。在 C++ 中,最接近的匹配是 a void *,但请注意它应该指向一个类结构。
我如何从 C++ 中显式调用它,operator+(a,b)风格中的东西?
你不应该那样做。您使用new或new[]。我假设gcc明确使用的函数名称的制造者通常无法从 C++ 程序中调用而不会由于名称冲突而出现语法错误。
这称为“放置new”,是在 C++03 中引入的。它的工作方式是,可以有一个 C++ 类围绕一组硬件寄存器,然后使用放置new将类准确地放在这些硬件寄存器之上。例如,如果一个基于硬件的硬件随机数发生器 (RNG) 是使用 32 位控制寄存器、状态寄存器和数据寄存器定义的,它们都从偏移 0x50000600 开始,您可以定义一个类:
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();
有关更多信息,请参阅此问题。