是否可以从某个对象的中间部分取消分配内存并"split"它?

Is it possible to partially de-allocate memory from the middle of some object and "split" it?

本文关键字:内存 分配 取消 split 中间部 对象 是否      更新时间:2023-10-16

例如,我有一个200个整数的数组。我要做的是把它转换成两个数组,每组80个整数,去掉中间的40个整数。当然,我们的目标是使用现有的内存块,而不是分配两个长度为80的整数数组并从第一个数组复制,我想要的是将初始数组从80削减到120,并将剩下的作为两个独立的数组。

Move语义使用类似的低级方法来避免不必要的右值复制,所以我的问题是是否有低级方法来实现类似的效果,但将已经存在的数据分配给多个对象。

例如,分配指针到原始内存地址的切割和新元素开始的位置,迫使它们作为使用相同数据的数组,已经分配和填充的初始数组?

当然,我也可以删除初始数组并获取其地址并使用该地址将其内存区域分配给新元素,但是是否有可能告诉c++在哪个确切的地址上分配新对象?而且,是否有一种方法可以保证初始数组的数据在删除和将相同的内存区域重新分配给新对象之间不会损坏?

在我读过的任何关于c++的书中都没有这样的方法,但我觉得很可能会有一些低级的技巧来达到预期的结果。

是的,这可以使用place -new。但是,无法保证在删除和重新分配之间不会更改内存位置的内容。无论如何,place -new只允许在内存中构造一个已经拥有的对象。所以你必须分配一个内存池,然后在这个池中做你自己的内存管理。

你可以使用placement new,但通常不是一个好主意,除非你真的有限制。

在下列情况下使用

  • 实现一个内存池
  • 你需要写一个精确的内存位置,因为平台需要(例如,内存映射I/O在一些嵌入式设备)。

使用的缺点:

    你需要确保分配的内存足够大来容纳对象。
  • 当对象不再需要时,需要显式地调用析构函数。

是否有一种方法可以保证初始数组的数据在其删除和将相同的内存区域重新分配给新对象之间不会损坏

不,这取决于操作系统。如果有特定于平台的API,这可能是可能的。

我要做的就是传递指向相关切片的指针:

void i_need_80(int arr[80]);  // same as "int*"
std::array<int, 200> the_array;
i_need_80(the_array);
i_need_80(the_array + 120);

std::array<int, 200>的位置,你也可以有一个动态的std::vector<int> v,在这种情况下,你可以说v.data()v.data() + 120

不要用new

您唯一能做的就是调用realloc()来调整(并可能移动)由realloc()的malloc()分配的块的大小。如果块是用new[]分配的,那么这也是不可能的。您需要重写(重新发明)内存管理函数malloc()、free()和realloc()。