是否可以从某个对象的中间部分取消分配内存并"split"它?
Is it possible to partially de-allocate memory from the middle of some object and "split" it?
例如,我有一个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()。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配