Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Вызов "new" в DLL; "delete" - в EXE == ERROR |
Автор: mr.DUDA 27.7.2003, 23:04 |
Кто-нибудь может предположить, почему когда вызван "стандартный" оператор new (мелкософт VC++ 6.0) внутри экспортируемой функции - нельзя освобождать выделенный блок вне DLL (будет исключение хипа) ? Ситуация такова: 1) в EXE есть глобальный указатель void *ptr 2) эта EXE загружает DLL с одной экспортируемой ф-цией 3) экспортируемая ф-ция получает указатель ч/з аргумент, выделяет блок памяти 10 байт -- "ptr=new char[10]" 4) DLL выгружается 5) в EXE вызывается "delete ptr" ======> получаем красное окно. Что сделано неправильно? В MSDN не сказано ничего о том, что для DLL и вызывающей EXE'шки существуют разные хипы. Даже адреса блоков памяти похожи, если выделить блок в EXE, а потом сразу же - в DLL. Кто знает, плиз help ![]() |
Автор: RAN 28.7.2003, 00:16 | ||
Нет, ошибка не в куче. DLL выделяет память от имени твоего процесса, так что удалять можешь смело. Проверь значение ptr в DLL и после возврата в EXE. Возможно ошибка в способе передачи параметра, ptr надо передавать по ссылке
|
Автор: mr.DUDA 28.7.2003, 10:45 | ||||
УРА !!! Нашел источник ошибки (Sorry за сильно упрощенный вопрос - оказалось, что проблема формулируется не так). НЕ делайте деструкторы виртуальными если объект создается в DLL а удаляется уже тогда, когда DLL выгружена ! Куча и в самом деле только одна, а вот сегмент кода - разный для EXE и DLL. Поэтому такой код приведет к ошибке: test_dll.dll:
test.exe:
А вот если поубирать "virtual" у деструкторов в EXE и в DLL - все будет Ok, т.к. физическое расположение функции CSome::~CSome будет в EXE (а не в DLL, как в приведенном примере). Если у кого-то появятся похожие траблы - пишите ! |
Автор: SMILic 16.4.2004, 22:11 |
привет, ты в паскале шариш??? ![]() Добавлено @ 22:15 эй мне просто помощь нужна а я здесь впервые, вот и не знаю куда потикнутся ??? посодействуй хоть крапаль, хотя бы ради солидарности ![]() |
Автор: Fantasist 16.4.2004, 22:50 |
На самом деле есть еще такая фигня, как менеджер памяти. То есть для выделения куска памяти new может обращатся к встроенному менеджеру памяти (как и delete для освобождения), который для dll и для exe может быть своим. Тут все зависит от реализации RTL. В Делфи происходит именно таким образом, поэтому менеджеры памяти существуют и в dll и в exe, поэтому там принципиально нельзя освобождать память выделенную в другом модуле, используя встроенный менеджер памяти. Правда там его тоже можно достадочно легко подменить и сделать его разделяемым. А вообще, идейно это не правильно. Память должна освобождаться там же, где и была выделенна. |
Автор: mr.DUDA 17.4.2004, 10:10 |
SMILic, я конечно рад помочь, но: 1) для этого вовсе не обязательно поднимать на форуме тему, созданную почти год назад, существует такая вещь как ПМ 2) по "паскалю" помогут товарищи, сидящие на форуме по Delphi Fantasist, в целом согласен, но вот какая фигня: создаётся ли при линковке DLL отдельный блок функций CRT, или используется тот, что и в EXE, подгрузившей данную DLL ?... В общем-то, суть оригинального вопроса была и не в этом, а в том, что когда DLL выгружается - соответственно все функции, в т.ч. и виртуальные методы классов - становятся недоступны, отчего генерируется исключение в случае вызова виртуального деструктора объекта, динамически созданного в DLL. Думаю, что на этом можно тему и закрыть, всем спасибо за ответы. |