安置新的开销[]

gez*_*eza 9 c++

当前的标准草案明确指出放置new[]可能有空间开销:

这种开销可以应用于所有数组新表达式,包括那些引用库函数operator new [](std :: size_t,void*)和其他放置分配函数的表达式.开销的数量可能因新的一次调用而异.

所以大概他们有一些想法,为什么编译器需要这个开销.它是什么?编译器可以将此开销用于任何有用的东西吗?

在我的理解中,要破坏这个数组,唯一的解决方案是在一个循环中调用析构函数(我是否正确?),因为没有放置delete[](顺便说一下,我们不应该有delete[]正确的方法来破坏数组,不仅仅是它的元素?).因此编译器不必知道数组长度.

我认为这个开销不能用于任何有用的东西,编译器不会使用它(所以这在实践中不是问题).我用这个简单的代码检查了编译器:

#include <stdio.h>
#include <new>

struct Foo {
    ~Foo() { }
};

int main() {
    char buffer1[1024];
    char buffer2[1024];

    float *fl = new(buffer1) float[3];
    Foo *foo = new(buffer2) Foo[3];

    printf("overhead for float[]: %d\n", (int)(reinterpret_cast<char*>(fl) - buffer1));
    printf("overhead for Foo[]  : %d\n", (int)(reinterpret_cast<char*>(foo) - buffer2));
}
Run Code Online (Sandbox Code Playgroud)

GCC和clang根本不使用任何开销.但是,MSVC使用8个字节的Foo情况.为什么MSVC会使用这种开销?


这是一些背景,为什么我提出这个问题.

之前有关于此主题的问题:

据我所知,这些问题的道德是避免使用放置new[],并new在循环中使用放置.但是这个解决方案不会创建一个数组,但是使用彼此相邻的元素(不是数组)operator[]是未定义的行为.这些问题更多的是关于如何避免安置new[],但这个问题更多的是关于"为什么?".

bar*_*top 1

动态数组分配是特定于实现的。但是实现动态数组分配的常见做法是在开始之前存储其大小(我的意思是在第一个元素之前存储大小)。这与以下内容完全重叠:

表示数组分配开销;new 表达式的结果将从运算符 new[] 返回的值中偏移此量。

“放置删除”没有多大意义。所做delete的就是调用析构函数和释放内存。delete对所有数组元素调用析构函数并释放它。显式调用析构函数在某种意义上是“放置删除”。

  • 我们已经知道“删除”需要开销。问题是:鉴于没有放置“delete”,为什么需要开销*特别是放置“new”*? (2认同)