为了账号安全,请及时绑定邮箱和手机立即绑定

数组放置-新需要缓冲区中未指定的开销?

数组放置-新需要缓冲区中未指定的开销?

C++
温温酱 2019-11-05 09:04:30
数组放置-新需要缓冲区中未指定的开销?5.3.4 [expr.new]2月11日的C+草案给出了一个例子:new(2,f) T[5]结果是operator new[](sizeof(T)*5+y,2,f).这里,x和y是表示数组分配开销的非负的未指定值;新表达式返回的值将由此金额抵消。operator new[]..此开销可应用于所有数组中。新表达式,包括引用库函数的那些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]会在内部打电话operator new[](sizeof(std::string) * 10 + y, buffer)(在构造个人之前)std::string)。问题是如果y > 0,预分配的缓冲区将太小!那么,当使用数组布局时,我如何知道要预先分配多少内存呢?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*)以及其他职位分配功能。
查看完整描述

3 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

经过一番讨论,我知道我的答案不再适用于这个问题。我会把它留在这里,但确实还需要一个真正的答案。

如果不能很快找到一个好的答案,我很乐意用一些赏赐来支持这个问题。

根据我的理解,我将在这里重申这个问题,希望一个较短的版本可以帮助其他人理解被问到的内容。问题是:

下面的结构总是正确的吗?是arr == addr最后?

void * addr = std::malloc(N * sizeof(T));T * arr = ::new (addr) T[N];                // #1

我们从标准中知道#1导致调用::operator new[](???, addr),在哪里???是不小于N * sizeof(T),我们也知道呼叫只会返回。addr也没有其他影响。我们也知道arr被抵消addr相应地。我们所做的知道的是内存是否指向addr是足够大的,或者我们如何知道要分配多少内存。


你似乎混淆了一些东西:

  1. 您的示例调用operator new[](),不是operator new().

  2. 分配函数不构造什么都行。他(她,它)们分配.

结果是表达 T * p = new T[10];原因:

  1. 打电话给operator new[]()带尺寸参数10 * sizeof(T) + x,

  2. 对默认构造函数的十个调用T,有效::new (p + i) T().

唯一的特点是数组-新的表达请求比数组数据本身使用的内存更多的内存。你没有看到任何这些,也不能以任何方式使用这些信息,除非是通过沉默的接受。


如果您想知道实际分配了多少内存,可以简单地替换数组分配函数。operator new[]operator delete[]把实际尺寸打印出来。


最新情况:作为一种随机的信息,你应该注意到全局布局-新的。功能都不需要行动。也就是说,当您就地构造一个对象或数组时,如下所示:

T * p = ::new (buf1) T;T * arr = ::new (buf10) T[10];

然后,相应的调用::operator new(std::size_t, void*)::operator new[](std::size_t, void*)除了回答他们的第二个论点外,什么也不做。但是,你不知道buf10应该指向:它需要指向10 * sizeof(T) + y内存字节,但您无法知道y.



查看完整回答
反对 回复 2019-11-06
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

调用任何版本的operator new[] ()对于固定大小的内存区域,不会工作得太好。本质上,它假定它委托给一些真正的内存分配函数,而不仅仅是返回一个指向分配内存的指针。如果您已经有了一个要构造对象数组的内存竞技场,则需要使用std::uninitialized_fill()std::uninitialized_copy()构造对象(或单独构造对象的其他形式)。

您可能会争辩说,这意味着您还必须手动销毁内存领域中的对象。然而,打电话delete[] array位置返回的指针new不起作用:它将使用非位置版本的operator delete[] ()!也就是说,当使用放置new您需要手动销毁对象并释放内存。



查看完整回答
反对 回复 2019-11-06
  • 3 回答
  • 0 关注
  • 322 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信