首页 > 解决方案 > 全局地图编译到多个共享对象的双重免费问题

问题描述

我有一个巨大的地图,需要多个共享对象..

//mymap.h
extern const std::unordered_map<int, std::string> gMAP;
std::string getname(int i) { return gMAP[i]; }

//mymap.cpp
extern const std::unordered_map<int, std::string> gMAP = {
  {1, "one" },
  {2, "two" },
  {3, "three" },
  ...
}

然后我有 library1 (lib1.so):

//CMakeLists.txt lib1.so
add_library(lib1 SHARED lib1.cpp mymap.cpp)

//lib1.cpp
#include "mymap.h"
void lib1_dosomething(int i) { std::cout << getname(i) << std::endl; }

然后我有 library2 (lib2.so):

//CMakeLists.txt lib2.so
add_library(lib2 SHARED lib2.cpp mymap.cpp)

//lib2.cpp
#include "mymap.h"
void lib1_dosomething(int i) { std::cout << getname(i) << std::endl; }

这只是我们复杂且更大的系统的伪代码。请注意,并非我们系统中的所有库都需要地图。只有极少数(这就是我在项目本身进行编译的原因)。

我对这种方式的理解如下:

  1. 每个编译“mymap.cpp”的库都有一个地图的“新”实例
  2. 系统运行时所有库都加载到内存中,不会有冲突。每个库在加载时创建全局映射,并在从内存中卸载时销毁它。

所以我的第一个问题是:这种理解正确吗?

但是,我在系统关闭期间发现了一个问题。我注意到每个库都按预期创建了一个实例,并在卸载期间销毁了它的实例。但是一个库似乎调用了 std::unordered_map 的析构函数两次。结果我们看到了一个释放错误(双重释放或损坏(!prev)),我无法解释为什么以及是什么导致了这种情况。有任何想法吗 ?

我正在考虑在自己的共享库中编译地图,以便我们在整个系统中只有一个实例,但我想了解为什么我看到“双重释放或损坏(!prev)”错误。

标签: c++memory-managementmemory-leaksshared-libraries

解决方案


推荐阅读