【问题标题】:C++ new/delete complexity guarantee by the standard标准的 C++ 新/删除复杂性保证
【发布时间】:2020-02-10 21:03:20
【问题描述】:

最近的 c++ 标准中的内存分配操作是否有复杂性保证? 也就是说,如果我有一个类 A,其默认构造函数和析构函数在 O(1) 中运行,那么“new A[N]”和“delete[] A”的大 O 是什么? 新的 int[N] 有没有复杂度保证?

【问题讨论】:

  • 在任何真实机器上,我看不出new 怎么可能小于 O(N),因为例如操作系统可能必须在将内存分配给您之前将其归零。跨度>
  • 也有点相关stackoverflow.com/questions/282926/…。我的问题中有“标准”。
  • N 个元素的数组的初始化将是 O(N)。但是,内存分配部分不清楚。所以我的问题主要是关于分配部分。
  • 如果标准保证对 STL 容器的操作性能,例如 vector::push_back,那么可以推断出 new 和 delete 的最坏情况性能,但它应该明确指定“new”的性能.

标签: c++ performance memory-management c++17 c++20


【解决方案1】:

我找不到任何明确提及复杂性的内容。我也很确定,对于新运算符(即内存分配本身),任何复杂性问题都是没有实际意义的。

有复杂的 C++ 运行时堆管理结构,建立在操作系统级内存管理之上,可能包括应用程序级锁、操作系统级锁、基于文件的交换等。出于这些原因,下面的答案不讨论内存分配本身。

但是,如果我们专注于新的表达,拼接在一起[expr.new/22]:

创建 T 类型对象的 new 表达式初始化 对象如下: (22.1) 如果省略 new-initializer,则 对象是默认初始化的 ([dcl.init])。

和[dcl.init/7]:

默认初始化 T 类型的对象意味着: .... (7.2) 如果 T 是 数组类型,每个元素都是默认初始化的。

我可以得出结论,这种操作的复杂度是 O(N)。

【讨论】:

  • 请一位可敬的反对者解释他们的反对意见吗?
【解决方案2】:

我怀疑是否有任何确切的保证,因为太多依赖于平台(想象一些非常奇怪的理论平台,没有人会制造但可以)。但是,您可以做出某些预期。如果构造和删除需要O(1) 那么...

delete A[] 的大小为nO(1)O(n),具体取决于A 是可简单破坏还是需要非平凡的删除过程。 O(1) 实际上可以很大(不是真正的O(1)),因为释放大量后续内存可能需要一些时间,但在更大范围内它仍然微不足道。

new A[n] 也是如此。如果A 可以简单构造(如int,即允许垃圾数据)或O(n),如果每个元素都需要一些O(1) 处理,则可能需要大约(假)O(1)

通常,您不应忘记A 的构造和销毁速度很慢并且可能需要大量时间的情况。

【讨论】:

  • 我可以想象当 delete A[] 为 O(N) 时听起来合理的实现,即使 A 是微不足道的破坏。假设系统出于安全考虑将释放的内存归零,或者需要更新页表条目等。您是否断言这将被标准禁止?
  • @NateEldredge 在第一段中声称标准并不真正打扰任何声明。首先,无法控制给定大小的分配/释放时间。那么这只是一般的预期。
猜你喜欢
  • 2010-09-15
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多