C++11 Feb草案的5.3.4 [expr.new]
给出了以下示例:
new(2,f) T[5]
会导致调用operator new[](sizeof(T)*5+y,2,f)
。这里,x和y是非负的未指定值,表示数组分配开销;new-expression的结果将从
operator new[]
返回的值偏移这个量。这种开销可以应用于所有数组new-expressions,包括那些引用库函数operator new[](std::size_t, void*)
和其他放置分配函数的表达式。开销的大小可能因每次新的调用而异。—示例结束
现在看下面的示例代码:
void* buffer = malloc(sizeof(std::string) * 10);
std::string* p = ::new (buffer) std::string[10];
根据上面的引用,第二行
new (buffer) std::string[10]
会在构建个别的std::string
对象之前内部调用operator new[](sizeof(std::string) * 10 + y, buffer)
。问题在于如果y > 0
,预分配的缓冲区将会太小!那么在使用数组就地新建时,如何知道要预先分配多少内存呢?void* buffer = malloc(sizeof(std::string) * 10 + how_much_additional_space);
std::string* p = ::new (buffer) std::string[10];
还是说标准在某处保证了在这种情况下
y == 0
?引用再次强调:
这个开销可能适用于所有的数组new-expressions,包括那些引用库函数
operator new[](std::size_t, void*)
和其他放置分配函数的表达式。
new
循环遍历数组呢?我认为这不会对性能产生太大影响,因为放置新对象基本上是一个空操作,而数组中所有对象的构造函数都必须单独调用。 - j_kubikdelete[]
几乎无法知道有多少个对象。 - Mooing Duckoperator new[]
和operator delete[]
的实现细节,在它们所在的任何范围内处理这个额外的开销,而不是将这个开销与最小所需空间一起传递。我认为这是最初的意图,但如果构造函数抛出异常,这可能会导致问题,如果不知道已经构造了多少个元素。C++真正缺少的是定义如何构造元素数组的方法。 - Adrian