我刚刚在研究性能问题时遇到了这个问题。一些在包含大缓冲区的对象上使用放置新的代码出乎意料地慢。原因:placement new 在调用构造函数之前将内存清零。
我对该标准的阅读与其他答案一致:编译器不需要做任何特别的事情。
但是,gcc 4.9、gcc 5.3、clang 3.4、clang 3.8 和 Apple clang 在放置新案例中似乎都将内存归零。检查汇编器输出,memset
在调用构造函数之前有一个显式调用。堆栈构造的对象不是零初始化的,所以它似乎不是构造函数在做这项工作。
检查来自 Dignus Systems/C++ for z/OS 的汇编器输出似乎也调用了一个库函数,大概是在做类似的事情(而且速度很慢)。
所以:放置 new 被允许将内存归零,并且似乎许多实现都将内存归零。
示例测试用例:
#include <new>
#include <cstdint>
#include <stdio.h>
struct Test {
char b[4];
void show(char const* prefix) {
for (unsigned i = 0; i < sizeof(b); ++i)
printf("%s index %d: %d\n", prefix, i, b[i]);
}
};
int main()
{
char* p = new char[sizeof(Test)];
for (unsigned i = 0; i < sizeof(Test); ++i)
p[i] = 'Q';
Test* t1 = new(p) Test();
Test t2;
t1->show("t1");
t2.show("t2");
}
示例输出(FreeBSD 上的 clang 3.4):
t1 index 0: 0
t1 index 1: 0
t1 index 2: 0
t1 index 3: 0
t2 index 0: 51
t2 index 1: -1
t2 index 2: 3
t2 index 3: 1