首页 > 解决方案 > 为什么没有 realloc 等同于 new/delete 系列?

问题描述

正如标题所说,我知道/系列运算符realloc中没有与 C 等效的。newdelete

我已经发现这个问题稍微触及了这个主题,但它并没有真正回答“为什么”。

我的问题是:

  1. 为什么能够重新分配对象是个坏主意?
  2. 为什么改变对象的大小是个坏主意?(实现一个集合似乎是一个对象改变其大小的完全正当理由。)
  3. 在这些情况下会违反什么规则,为什么这条规则客观上是好的?

标签: c++memorymemory-management

解决方案


Realloc 有两种行为,其中一种在 C++ 对象模型中是不可接受的。Realloc 可以增加一块存储的大小,或者它可以分配新的存储并将旧存储中的所有内容复制到新存储中。

问题是,C++ 并不认为对象只是比特袋。它们是具有不变量的活生生的呼吸类型。而且其中一些不变量不能容忍它们的位被很好地复制。

在 C++ 中,复制对象的位并不意味着您有效地复制了该对象。这仅适用于可简单复制的类型,并且有很多类型不可简单复制。

因此,C++ realloc 等价物不能用于任何分配。您需要将调用拆分为两个单独的调用:一个尝试扩展内存,如果不能,则不执行任何操作,以及您将使用现有 C++ 技术手动复制到的常规堆分配调用。


作为一个例子,许多std::list实现在对象本身中存储了一个终止节点,std::list用于表示链表的开始/结束。如果您只是简单地复制其位,则指向终止节点的指针将指向现在已消失的旧分配。

那很糟。

为了允许对象具有访问这些类型的代码可以维护的任意类不变量,有必要将对象视为不仅仅是其对象表示的位。并且大多数 C++ 类型都保留了一些不变量,其对象表示无法在按位复制中存活。


推荐阅读