C++模板和标头分配

sel*_*rer 5 c++ memory templates allocation

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

  • 它只是不起作用 - 在调试时失败了assert().
  • 如果一个DLL与标准C库静态链接并且另一个DLL与其动态链接,则它不起作用.
  • 如果一个DLL执行分配然后卸载DLL并且另一个DLL尝试释放此内存,则它不起作用.

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

当我确实需要在模板中创建一个新对象时,我现在所做的就是为它分配一个cpp文件的内存,然后只使用placement new运算符运行它的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 );
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但这有点难看.这意味着不使用new就编写模板代码.

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

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

Lig*_*ica 4

基本上,我决定应该遵循的规则是不要在一个 DLL 中进行分配并在另一个 DLL 中释放它(最好将其保留在一个 cpp 文件中)。这通常也意味着我不应该在可能由多个 DLL 共享的头文件中进行分配。

不,一个并不意味着另一个。

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

封装您的对象,以便 DLL 1 中的代码对 DLL 2 中的对象调用这些函数是无效/禁止/未定义的。与用户签订合同,在注释中写下对象的所有权仍保留在原始分配中上下文,然后继续项目的下一部分,而不必再担心这个问题。

所有 TU 都可以使用这些功能并不相关;毕竟,你总是可以尝试delete这些事情!


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