1

例如,我有一个包含 200 个整数的数组。我想要做的是将它转换为两个 80 个整数的数组,删除其间的 40 个整数。目标当然是使用现有内存块而不分配两个长度为 80 整数的新数组并从第一个数组复制,我想要的是将初始数组从 80 剪切到 120 并将剩下的视为两个单独的数组。

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

例如,将指针分配到剪切位置和新元素开始的原始内存地址,强制它们充当使用相同数据的数组,已经分配并由初始数组填充?

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

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

4

4 回答 4

2

是的,这可以使用placement-new来实现。但是,无法保证在删除和重新分配之间不会更改内存位置的内容。无论如何,placement-new 只能让您在内存中构造一个您已经拥有的对象。因此,您必须分配一个内存池,然后在该池中进行自己的内存管理。

于 2011-11-29T13:29:39.613 回答
2

您可以使用placement new,但通常不要使用这种低级别,除非您真的受到限制。

在以下情况下使用它是个好主意:

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

使用它的缺点:

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

有没有办法保证初始数组的数据在删除和将同一内存区域重新分配给新对象之间不会被破坏

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

于 2011-11-29T13:30:50.437 回答
2

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

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.

于 2011-11-29T13:39:21.097 回答
0

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

于 2011-11-29T13:32:36.483 回答