Недавно я столкнулся с проблемами с выделением памяти в одной DLL (или * .so - переносимым кодом) и освобождением в другой DLL.До сих пор встречались следующие ошибки:
- Это просто не работает - не удается выполнить assert () при отладке.
- Это не работает, если одна DLL статически связана сстандартная библиотека C и другая DLL, динамически связанная с ней.
- Не работает, если одна DLL выполняет выделение, тогда DLL выгружается, а другая DLL пытается освободить эту память.
По сути, я решил придерживаться правила, которое заключается в том, чтобы не делать выделения в одной DLL и освобождать ее в другой (и желательно хранить в одном файле cpp).Обычно это также означает, что я не должен делать выделения в заголовочном файле, который может совместно использоваться более чем одной DLL.Это означает Я не должен делать выделения в tempaltes (так как они все в заголовке), и это довольно большое ограничение.
Когда мне нужно создать новый объект в шаблонечто я сейчас делаю, так это выделяю память для этого файла cpp и только потом запускаю его c'tor с оператором размещения new.
// 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.Фактически, одно из мест, с которыми я столкнулся, было в векторе, размер которого был изменен одной динамической библиотекой (в HP-UX), а затем выгружен по сравнению с тем, как его d'tor был вызван другой динамической библиотекой.
Есть ли некоторыешироко известное решение для этого, что я просто пропускаю или это просто упущенная проблема?