数组布局 - 新需要缓冲区中的未指定开销? [英] Array placement-new requires unspecified overhead in the buffer?
问题描述
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屋!