#cpp #windows #malloc
Если в библиотечной функции выделяется блок динамической памяти, передача указателя в загрузившее эту библиотеку приложение может привести к неприятным последствиям. С чем это связано? Я конечно понимаю, что у загруженной DLL будет свой менеджер памяти, и загружаться она будет в область разделяемой памяти. Это значит, что переменные, объявляемые в ней будут хранится в каком то своём стеке, а динамически выделяемая память расположена в своей "куче". malloc внутренне, вроде как, хранит сколько он памяти выделил и где, поэтому при вызове free, если менеджер памяти тот же, тоже знает расположение этой информации и знает сколько памяти освободить. Таким образом, при передаче указателя на память, выделенную в DLL, free не будет знать сколько памяти освободить. В принципе, возвращаемый библиотечной функцией указатель можно использовать в любой программе, запущенной на той же машине?
Ответы
Ответ 1
Вопрос сформулирован бессмысленно. Никакого "нельзя" тут не существует и никогда не существовало. Вы можете передавать в/из DLL любые указатели. Никаких противопоказаний для этого нет - это фундаментально необходимая возможность и отказываться от нее вам никто не предлагает. передача указателя в загрузившее эту библиотеку приложение может привести к неприятным последствиям Сама передача указателя НЕ может привести к неприятным последствиям. Попытка освобождения указуемой памяти на территории другого модуля может. У загруженной DLL может быть свой менеджер памяти. А может и не быть. Это зависит от конфигурации этой DLL. Это единственная деталь, которую нужно помнить: не предполагайте, что вы имеете право напрямую уничтожать объекты, выделенные внутри DLL. Вполне может оказаться так, что все объекты, созданные в DLL, должны передаваться обратно в DLL для уничтожения.Ответ 2
Это возможно, но этого не делают. Причина может быть в том что библиотека и вызывающий ее модуль могут использовать разные аллокаторы, а потом вы воспользуетесь своим деаллокатором в вызывающем модуле? А если этот модуль - тоже библиотека, и указатель был передан выше? Эти библиотеки обладают своими методами отслеживания ресурсов, и глобальные объекты для выполения этих функций разные , если аллокаторы разные. Какие именно - зависит от компилятора и его версии\сборки. Даже если в конечном итоге все они вызывают GlobalAlloc\GlobalFree. Вызовы разных версий библиотеки времени исполнения обращаются к разным экземплярам фунций. А это, как история показала, в случае с майкрософтской библиотекой приводит к нарушению целостности кучи. Область памяти размещенной с помощью 8й студии не удалится вызовом функции из библиотеки 10й студии, и т.п. DLL была откомпилирована в 8 а программа - в 10й. Иногда даже номера сборок имели значение. Хорошим тоном является либо предоставление механизма создания и уничтожения объекта, либо, что предпочтительнее, выделение памяти вызывающим. Последний исключает всякую возможность того, что менеджер памяти из DLL будет конфликтовать с программой. .
Комментариев нет:
Отправить комментарий