5.3.4 [expr.new]
C++11 Feb 草案给出了示例:
new(2,f) T[5]
结果调用operator new[](sizeof(T)*5+y,2,f)
.
这里,x和y是非负未指定值,表示数组分配开销;的结果新表达将从返回的值中抵消此金额operator new[]
。此开销可能适用于所有数组新表达,包括那些引用库函数的operator new[](std::size_t, void*)
和其他布局分配功能。每次 new 调用与另一次调用之间的开销量可能会有所不同。—结束示例 ]
现在采用以下示例代码:
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
,预分配的缓冲区会太小!
那么,在使用 arrayplacement-new 时,我如何知道要预分配多少内存呢?
void* buffer = malloc(sizeof(std::string) * 10 + how_much_additional_space);
std::string* p = ::new (buffer) std::string[10];
或者某处的标准是否保证y == 0
在这种情况下?再次,引用说:
此开销可能适用于所有数组新表达,包括那些引用库函数的operator new[](std::size_t, void*)
和其他布局分配功能。
Update
Nicol Bolas 在下面的评论中正确地指出,这个问题已被修复,这样开销始终为零operator new[](std::size_t, void* p) http://eel.is/c++draft/expr.new#19.sentence-1.
此修复是作为缺陷报告 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2382于 2019 年 11 月发布,这使其追溯至 C++ 的所有版本。
原答案
不要使用operator new[](std::size_t, void* p)
除非你先验地知道这个问题的答案。答案是实现细节,并且可以随编译器/平台的不同而改变。尽管它对于任何给定平台通常都是稳定的。例如。这是由安腾ABI http://sourcery.mentor.com/public/cxx-abi/.
如果您不知道这个问题的答案,请编写自己的新放置数组,以便在运行时检查:
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
为您的平台。为了我的平台 http://sourcery.mentor.com/public/cxx-abi/ y
是 1 个字。 sizeof(word) 根据我是针对 32 位还是 64 位体系结构进行编译而有所不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)