我在一个产品中工作,其中大多数模块都是用C语言编写的。其中,一个或两个模块是用C ++编写的。我在C ++模块中找到了以下代码,我无法理解发生了什么。
a = (char *) malloc (size);
b = new (a) MyClass();
有人可以解释一下malloc分配的指针是如何用于新运算符的吗?这是合法的吗?
谢谢!
答案 0 :(得分:3)
b = new (a) MyClass();
被称为 placement new ,它在预先分配的内存(指针MyClass
指向的内存)上构造类型为a
的新对象。
您还应该检查此问题:What uses are there for "placement new"?
答案 1 :(得分:2)
new可以接受参数,它告诉新的内存的起始地址......所以代码正在做的是......
a = (char *) malloc (size);
分配新类的内存......
b = new (a) MyClass();
告诉新用户' a'作为记忆的起始地址,并在' a'的地址处初始化clas。 ...
答案 2 :(得分:0)
语法new (something) Type
称为展示位置
新。像所有new
一样,它调用分配器函数,然后调用
Type
的构造函数。分配器函数具有签名:
void* operator new( size_t byteCount, something );
换句话说,无论你放在括号中的是什么都传递给
operator new
函数的其他参数。
除了通常的operator new
函数之外,标准还定义了
另外两个operator new
函数,它们带有其他参数:
void* operator new( size_t byteCount, std::nothrow_t ) noexcept;
和
void* operator new( size_t byteCount, void* where ) noexcept;
请注意,两者都是noexcept
。第一个返回空指针if
分配失败(而不是抛出bad_alloc
),第二个
只需返回where
。 (第二个也称为贴新品。
这导致了混乱的结束:“放置新”可以
引用任何扩展的新内容,或者引用一个void*
的内容。)
在你的情况下,第二个是正在使用的,虽然我愿意 严重质疑为什么:如果对象类型有析构函数,你会 必须这样做:
b->~MyClass();
free( b );
删除它。 (通常使用放置新显式删除和显式删除
您希望将分配与初始化分开的情况。在一个
例如,std::vector
的实施,其中容量可以是。{1}}
大于这个尺寸。)我能看到它的唯一原因
是对象必须在C ++中分配,但将在C中删除
(当然,它有一个简单的析构函数 - 否则,没有
方式C可以正确删除它。)