C++ 模板和 header 分配

标签 c++ templates memory allocation

我最近遇到了在一个 DLL(或 *.so - 可移植代码)中分配内存和在另一个 DLL 中释放内存的问题。目前我遇到的错误是:

  • 它只是行不通 - 调试时 assert() 失败。
  • 如果一个 DLL 与标准 C 库静态链接而另一个 DLL 与其动态链接,则无法正常工作。
  • 如果一个 DLL 进行了分配,然后该 DLL 被卸载并且另一个 DLL 试图释放该内存,则它不起作用。

基本上我决定应该遵循的规则是不要在一个 DLL 中进行分配并在另一个 DLL 中释放它(最好将其保存在一个 cpp 文件中)。这通常也意味着我不应该在可能被多个 DLL 共享的头文件中进行分配。这意味着我不应该在 tempaltes 中进行分配(因为它们都在 header 中),这是一个很大的限制。

当我确实需要在模板中创建一个新对象时,我现在要做的是为其分配一个 cpp 文件的内存,然后才使用放置新运算符运行它的 c'tor。

// header
class MyBase
{
public:
  static void* allocate(std::size_t i_size);
};

template <typename T>
class MyClass: MyBase
{
public:
  T* createT();
};

temlpate <typename T>
T* MyClass<T>::createT()
{
  void* pMem = MyBase::allocate( sizeof(T) );
  return new (pMem) T;
}

// Cpp file
void* MyBase::allocate(std::size_t i_size)
{
  return malloc( i_size );
}

虽然这可行,但有点难看。意思是不使用new写模板代码。

另一个含义是,如果您不知道模板是使用这种技术编写的,您应该只在头文件(包括其他模板)中使用它的 const 方法(这是假设 const 方法不分配或释放内存)。这包括 STL。事实上,我遇到的一个地方是在一个 vector 中,该 vector 由一个动态库(在 HP-UX 上)调整大小然后卸载,而不是它的 d'tor 被另一个动态库调用。

是否有一些我只是缺少的广为人知的解决方案,或者它只是一个被忽视的问题?

最佳答案

Basically the rule I decided I should follow is not to make allocations in one DLL and release it in another (and preferably keep it within one cpp file). This usually also means I shouldn't do allocations in a header file that may be shared by more than one DLLs.

不,一个暗示另一个。

如果您的分配和取消分配函数是 header 中的模板,那也没关系;只需确保将任何给定对象的这些函数的使用限制为一个 TU1

封装您的对象,使 DLL 1 中的代码对 DLL 2 中的对象调用这些函数无效/禁止/未定义。使其成为用户的契约(Contract),将其写在对象所有权保留的注释中原始分配上下文,然后继续到项目的下一部分,而无需再次担心。

与所有 TU 都可用的功能无关;毕竟,您可以始终尝试删除这些东西!


1 - 翻译单元。大致相当于一个预处理的 .cpp 文件。

关于C++ 模板和 header 分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5961735/

相关文章:

C++ 从文件中输入

c++ - 如何使用 Rcpp 和内联设置 g++ 编译器标志?

c++ - Xerces 安装后找不到库

c++ - 模板参数中的 const

python - 产生一个进程是处理 python 内存泄漏的好方法吗?

c++ - 字节数组及其大小的良好表示

C++ - 如何创建一个可以在类中与 _ 一起使用的属性?

c++ - 根据构造函数参数推导模板类型

c++ - DLL注入(inject)和偏移读内存

c++ - 线程分配的内存块是否与线程本身具有相同的亲缘关系,直到线程退出?