c++ - 将 C++ 对象(尤其是 STL 容器)移动到特定的内存位置

标签 c++ memory stl

我正在与一个内存管理器合作,该管理器有时需要对内存进行碎片整理。基本上,我将遍历内存管理器分配的对象列表并重新定位它们:

class A {
  SomeClass* data; // This member is allocated by the special manager
};

for(... each instance of A ...) 
    a.data = memory_manager.relocate(a.data);

memory_manager.relocate()memcpy() 数据的内容移动到一个新的位置,并返回指针。

虽然它通常不是 memcpy() C++ 类的惯用方法,但在这种情况下它似乎是一个有用的解决方案,考虑到我控制了将与内存管理器。

问题是其中一个类使用了 std::map,就我而言这是一个不透明的类。我当然不认为我可以 memcpy() 它。我可能无法在任何情况下使用 std::map 。据我所知,它可以分配几 block 内存。

我能想到的最佳解决方法非常简单。由于碎片内存管理器会将新分配放在更有利的位置,我需要做的就是重新分配它,然后删除旧的:

for(... each instance of A ...) {
    stl::map<something>* tmp = a.the_map;
    a.the_map = new stl::map<something>(tmp);
    delete tmp;
}



无论如何,这让我想知道:

C++ 是否具有将对象移动/复制到特定内存位置的语义或习语?

是否可以将 STL 容器的内容移动到特定的内存位置?


编辑:虽然我没有指出,但我显然会将分配器参数传递给 std::map。根据我得到的信息丰富的答案,我意识到我在最初的问题中发布的解决方法可能是减少碎片化的唯一方法。通过使用 map 的复制构造函数(和分配器模板参数), map 使用的所有内存都将被正确地重新分配。

正如评论所指出的,这主要是一个理论问题。内存碎片很少需要担心。

最佳答案

每次你插入一个新的键值对时, map 都会分配一个节点来存储它。这种分配如何发生的细节由 map 使用的分配器决定。

默认情况下,当您在 std::map<K,V> 中创建 map 时使用默认分配器,它在堆上创建节点(即 new/delete )。

您不希望这样,因此您必须创建一个自定义分配器类,该类根据内存管理器的指示创建节点。

创建分配器类并不简单。 This code显示了如何完成,您必须根据自己的需要对其进行调整。

一旦你有了你的分配器类(假设你称之为 MemManagerAllocator ),你必须将你的映射定义为 std::map<K, V, MemManagerAllocator>然后像使用普通 map 一样使用它。

就个人而言,我需要有一个非常糟糕的内存碎片问题才能解决所有这些麻烦。

关于c++ - 将 C++ 对象(尤其是 STL 容器)移动到特定的内存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2244010/

相关文章:

c++ - 是否定义了sprintf(b, “%”)?

c++ - 使c++编译器优化以在 map 初始化中调用一次构造函数

c - 如何将 uint8 * 转换为包含可变长度数组元素的结构? (C 编程)

c++ - 使用模板时如何使用 STL 容器的 size_type 类型?

c++ - std::binary_search 的自定义比较函数

c++ - 将 Q_DECLARE_METATYPE 与可能被多次加载的 DLL 一起使用

c++ - mbed MemoryPool - 它可用于重要的类吗?

java - Java 8 与 Java 9 之间的内存分配是否存在差异?

c - 查找上次释放内存的位置?

c++ - C++中队列的时间复杂度