Linux C/C++ выделяет/освобождает память в динамической библиотеке

Мне нужно разделить мое приложение на несколько логических модулей.

mainapp:

  • module1.so
  • module2.so
  • module3.so
  • и так далее

Где каждый модуль представляет собой *.so библиотеку, которая будет загружаться во время выполнения.

Каждый модуль использует один и тот же интерфейс и возвращает некоторый массив данных. Например:

int *ptr = module1->getIntData();

Можно ли освободить/удалить эту память на стороне mainapp?

int *ptr = module1->getIntData();
delete ptr; //(or free(ptr))

Как насчет реализации malloc/free. Возможно ли, что эта библиотека будет использовать другую, а не mainapp?


person Dejwi    schedule 05.04.2016    source источник
comment
Вы, вероятно, в порядке, однако кажется, что если вы предоставляете метод createThing(), вы также должны предоставить метод destroyThing() для согласованности, если ничего другого.   -  person trojanfoe    schedule 05.04.2016
comment
Вы следуете какому-либо механизму синхронизации? например mutex или что-то еще.   -  person someone    schedule 05.04.2016
comment
На самом деле это скорее вопрос соглашения, чем технический вопрос. То есть технически это нормально, но важно явно согласовать, какая сторона владеет данными, выделенными библиотечными методами.   -  person user3159253    schedule 05.04.2016
comment
Также я бы предложил вернуть что-то вроде std::unique_ptr, а не raw указатели, потому что unique_ptr/shared_ptr позволяют указывать средства удаления при создании объекта, тем самым упрощая управление памятью и делая явные функции удаления излишними.   -  person user3159253    schedule 05.04.2016
comment
Выбор между unique_ptr, shared_ptr и weak_ptr зависит от политики владения.   -  person user3159253    schedule 05.04.2016


Ответы (1)


Я бы настоятельно рекомендовал, чтобы модуль, который выполняет выделение, также отвечал за освобождение. Таким образом:

int *ptr = module1->getIntData();
...
module1->freeIntData(ptr);

Это позволяет различным модулям без труда использовать разные распределители (malloc/free, new/delete, slab allocator и т. д.).

В системах Posix в процессе может быть только одна реализация mallocfree), поэтому, если определение getIntData "возвращает указатель, который должен быть освобожден free", тогда все будет в порядке. С другой стороны, я думаю, что можно было бы написать два компилятора C++, которые можно было бы использовать для написания модуля1 и модуля2, но которые не могли delete памяти выделять другим new. (Хотя я думаю, что такие компиляторы в настоящее время не существуют).

Если есть малейший проблеск шанса, что вам когда-либо придется портировать эту партию на Windows, тогда вы действительно хотите, чтобы модули освобождали выделенную ими память. Различные библиотеки DLL могут иметь разные кучи, что может привести к всевозможным забавным проблемам. (Как говорит @trojanfoe в комментариях: одной лишь разницы между сборками отладки и выпуска может быть достаточно, чтобы вызвать горе.)

Я бы рекомендовал использовать std::unique_ptr только в том случае, если вы можете гарантировать, что все модули всегда будут собираться с использованием одной и той же версии одного и того же компилятора с использованием одинаковых флагов компилятора. (Я твердо верю в то, что интерфейсы динамических библиотек должны быть как можно более простыми и похожими на C.)

person Martin Bonner supports Monica    schedule 05.04.2016
comment
убедиться, что должно получиться. Кроме того, если мне не изменяет память, требуется только создание Windows DLL в режиме отладки и исполняемый файл в режиме выпуска, чтобы продемонстрировать проблему, которую вы решаете с помощью своего ответа. - person trojanfoe; 05.04.2016
comment
std::unique_ptr может быть хорошим, так как я могу передать ему пользовательский (библиотека) делокатор. - person Dejwi; 05.04.2016
comment
@trojanfoe: Ха! Хорошая оговорка по Фрейду :-) - person Martin Bonner supports Monica; 05.04.2016
comment
@Dejwi: я бы не стал доверять компиляторам/библиотекам, чтобы std::unique_ptr имел один и тот же ABI в сборках отладки и выпуска. - person Martin Bonner supports Monica; 05.04.2016