C++11 2月草案的
5.3.4 [expr.new]
给出了例子:
new(2,f) T[5]
results in a call ofoperator new[](sizeof(T)*5+y,2,f)
.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 functionoperator 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
,预分配的buffer会太小!
那么我怎么知道在使用arrayplacement-new时要预分配多少内存呢?
void* buffer = malloc(sizeof(std::string) * 10 + how_much_additional_space);
std::string* p = ::new (buffer) std::string[10];
或者在这种情况下,某处的标准是否保证 y == 0
?再次,引用说:
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.
最佳答案
更新
Nicol Bolas 在下面的评论中正确指出,此问题已得到修复,the overhead is always zero for operator new[](std::size_t, void* p)
.
此修复是作为 defect report 完成的2019 年 11 月,这使得它可以追溯至所有 C++ 版本。
原答案
请勿使用 operator new[](std::size_t, void* p)
除非您先验地知道该问题的答案。答案是一个实现细节,可以随着编译器/平台而改变。尽管它对于任何给定平台通常都是稳定的。例如。这是 Itanium ABI 指定的内容.
如果你不知道这个问题的答案,写你自己的放置数组 new 可以在运行时检查这个:
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];
}
通过改变数组大小并检查上面示例中的 n
,您可以推断出适合您平台的 y
。对于 my platform y
是 1 个单词。 sizeof(word) 取决于我是针对 32 位还是 64 位架构进行编译。
关于c++ - 新数组放置需要缓冲区中未指定的开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8720425/