如何防止 C++ new/delete 中的内存间隙?

How to prevent memory gaps in C++ new/delete?

本题基于https://arduino.stackexchange.com/questions/81857/what-would-be-the-best-way-of-dynamically-change-instances-regarding-dynamic-m

我有一个基础 class,并且(可能)有许多从它派生的 classes。我想对那些派生的 classes 有 4 个实例,但这些实例发生了变化。例如。假设派生 classes C1..C20,则删除 C4 的一个实例,并创建一个新实例 C7。

由于内存限制,我无法创建所有派生的 4 个实例 class。

我在 Arduino 平台上工作。我可以假设:

  1. 当我delete一个实例和new一个实例,并且导出的classes没有任何实例变量时,内存差距由delete第一个instance,会被new创建的instance填充吗?请注意派生的 classes 有不同的方法(但我认为这只影响 V-table)。
  2. 我可以假设,当实例使用的内存量相同时也是如此吗? (例如,如果基础 class 使用 10 个字节,派生实例使用 20 个字节,而新实例也使用 20 个字节,它将使用相同的 space?

如果情况 2 成立,保持两个实例(内存)大小相同的最佳方法是什么?就像为差异放置一个未使用的字节数组,例如:

class C
{ 
   byte a;
}

class C1: C
{
   byte a;
   long b;
}

class C2: C
{
   byte a;
   byte _unused[4];
}

我猜我还必须考虑对齐?

你必须确保

  • 您有足够的内存来容纳任何派生类型的 4 个实例。
  • 内存对齐适用于所有派生类型。

然后您可以分配足够的内存来容纳 4 个实例并使用 new(buffer) Type 来构建实例。完成并想要切换类型后,您可以在每个实例上调用析构函数,并对其他类型使用 placement new。

在这种非常特殊的情况下,您可以使用 union 您想要使用的所有类型。这保证您始终为最大的 class 分配足够的内存,而无需任何手工代码。因此,您不需要编写 sizeof(largest_type).

的手工版本

之后,您可以根据需要进行 deletenew at

顺便说一句:那是 classic 用例 std::variant

问题是没有arduino platform! Arduino 可以从没有任何 STL 支持的 AVR 8 位控制器到支持所有一切的 ARM。不知道你是否可以使用 std::variant.