数组布局 - 新需要缓冲区中的未指定开销? [英] Array placement-new requires unspecified overhead in the buffer?

查看:100
本文介绍了数组布局 - 新需要缓冲区中的未指定开销?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

5.3.4 C ++ 11 Feb草案中的 [expr.new] 提供了示例:

5.3.4 [expr.new] of the C++11 Feb draft gives the example:


new(2,f)T [5] 导致调用 operator new [](sizeof )* 5 + y,2,f)

这里,x和y是表示数组分配开销的非负非未定义值; new-expression 的结果将被 operator new [] 返回的值所抵消。这个开销可以应用于所有数组 new-expressions ,包括引用库函数 operator new [](std :: size_t,void *)和其他布局分配功能。开销的量可以从一个新的调用到另一个调整。 -end example ]

Here, x and y are non-negative unspecified values representing array allocation overhead; the result of the new-expression will be offset by this amount from the value returned by operator new[]. This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. The amount of overhead may vary from one invocation of new to another. —end example ]

现在取以下示例代码:

void* buffer = malloc(sizeof(std::string) * 10);
std::string* p = ::new (buffer) std::string[10];

根据上面的引用,第二行 new(buffer)std: :string [10] 将在内部调用 operator new [](sizeof(std :: string)* 10 + y,buffer)个别 std :: string 对象)。问题是如果 y> 0 ,预分配的缓冲区太小了!

According to the above quote, the second line new (buffer) std::string[10] will internally call operator new[](sizeof(std::string) * 10 + y, buffer) (before constructing the individual std::string objects). The problem is that if y > 0, the pre-allocated buffer will be too small!

那么如何知道在使用数组布局时要预分配多少内存-new?

So how do I know how much memory to pre-allocate when using array placement-new?

void* buffer = malloc(sizeof(std::string) * 10 + how_much_additional_space);
std::string* p = ::new (buffer) std::string[10];

或者标准在某处保证 y == 0 在这种情况下?同样,引用说:

Or does the standard somewhere guarantee that y == 0 in this case? Again, the quote says:


这种开销可能应用于所有数组 new- expressions ,包括引用库函数 operator new [](std :: size_t,void *)和其他放置分配函数。


This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions.


推荐答案

不要使用 operator new [](std: :size_t,void * p),除非你知道这个问题的答案。答案是一个实现细节,可以随编译器/平台而改变。虽然它对于任何给定的平台通常是稳定的。例如。这是由 Itanium ABI 指定的内容。

Don't use operator new[](std::size_t, void* p) unless you know a-priori the answer to this question. The answer is an implementation detail and can change with compiler/platform. Though it is typically stable for any given platform. E.g. this is something specified by the Itanium ABI.

如果您不知道此问题的答案,请写入您自己的展示位置数组,以便在运行时检查此位置:

If you don't know the answer to this question, write your own placement array new that can check this at run time:

inline
void*
operator new[](std::size_t n, void* p, std::size_t limit)
{
    if (n <= limit)
        std::cout << "life is good\n";
    else
        throw std::bad_alloc();
    return p;
}

int main()
{
    alignas(std::string) char buffer[100];
    std::string* p = new(buffer, sizeof(buffer)) std::string[3];
}

通过改变数组大小并检查 code>在上面的例子中,你可以推断 y 为您的平台。对于我的平台 y 为1个字。 sizeof(字)取决于我是为32位还是64位架构编译。

By varying the array size and inspecting n in the example above, you can infer y for your platform. For my platform y is 1 word. The sizeof(word) varies depending on whether I'm compiling for a 32 bit or 64 bit architecture.

这篇关于数组布局 - 新需要缓冲区中的未指定开销?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆