为什么运行时环境决定不应用删除或删除[]而不是程序员?

Pet*_*uza 18 c++ memory-management dynamic-memory-allocation

我已经读过delete[]需要运算符,因为运行时环境不会保留有关分配的块是否是需要析构函数调用的对象数组的信息,但它确实保留了有关存储分配块的内存位置的信息,当然还有块的大小.
如果需要在删除时调用析构函数,还需要记住一点元元数据,那么为什么不这样做呢?

我很确定有一个很好的解释,我不是在质疑它,我只想知道它.

Mar*_*k B 10

我认为原因是C++不会强迫你进入任何你不想要的东西.它会添加额外的元数据,如果有人不使用它,那么额外的开销就会强加给它们,这与C++语言的设计目标形成对比.

当您需要所描述的功能时,C++ 确实提供了一种方法.它被调用std::vector,你应该几乎总是喜欢它,另一种容器,或智能指针超过原始newdelete.


Mat*_* M. 3

这里有两件事需要澄清。

malloc第一:保持您要求的精确尺寸的假设。

并不真地。malloc只关心提供一个足够大的块。尽管出于效率原因,它可能不会过度分配太多,但它仍然可能会为您提供一个“标准”大小的块,例如字节2^n块。因此,实际大小(如实际分配的对象数量)实际上是未知的。

第二:需要的“额外位”

事实上,给定对象知道它是否是数组的一部分所需的信息只是一个额外的位。从逻辑上讲。

但就实施而言:您实际上会将这一点放在哪里?

为对象本身分配的内存可能不应该被触及,毕竟对象正在使用它。所以 ?

  • 在某些平台上,这可以保留在指针本身中(某些平台忽略一部分位),但这不可移植
  • 因此它需要额外的存储空间,至少一个字节,但由于对齐问题,它很可能达到 8 个字节。

演示:(如某所指出的那样不令人信服,见下文)

// A plain array of doubles:
+-------+-------+-------
|   0   |   1   |   2   
+-------+-------+-------

// A tentative to stash our extra bit
+-------++-------++-------++
|   0   ||   1   ||   2   ||
+-------++-------++-------++

// A correction since we introduced alignment issues
// Note: double's aligment is most probably its own size
+-------+-------+-------+-------+-------+-------
|   0   |  bit  |   1   |  bit  |   2   |  bit
+-------+-------+-------+-------+-------+-------
Run Code Online (Sandbox Code Playgroud)

哼!

编辑

因此,在大多数平台上(地址确实很重要),您将需要“扩展”每个指针,并且实际上将它们的大小加倍(对齐问题)。

是否可以接受所有指针都是两倍大,以便您可以隐藏额外的位?对于大多数人来说,我想是的。但 C++ 并不是为大多数人设计的,它主要是为关心性能(无论是速度还是内存)的人设计的,因此这是不可接受的。

编辑结束

那么正确答案是什么呢?正确的答案是恢复类型系统丢失的信息代价高昂。很遗憾。