Модераторы: Daevaorn
  

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> Вызов "new" в DLL; "delete" - в EXE == ERROR, Сабж, непонятно в чем кроется баг. 
:(
    Опции темы
mr.DUDA
  Дата 27.7.2003, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Кто-нибудь может предположить, почему когда вызван "стандартный" оператор 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 confused.gif


--------------------
user posted image
PM MAIL WWW   Вверх
RAN
Дата 28.7.2003, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Нет, ошибка не в куче. DLL выделяет память от имени твоего процесса, так что удалять можешь смело.
Проверь значение ptr в DLL и после возврата в EXE. Возможно ошибка в способе передачи параметра, ptr надо передавать по ссылке
Код

void DLLFunction(void*& ptr)
{
   ptr = new char[10];
}


PM MAIL ICQ   Вверх
mr.DUDA
Дата 28.7.2003, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



УРА !!!
Нашел источник ошибки (Sorry за сильно упрощенный вопрос - оказалось, что проблема формулируется не так).

НЕ делайте деструкторы виртуальными если объект создается в DLL а удаляется уже тогда, когда DLL выгружена ! Куча и в самом деле только одна, а вот сегмент кода - разный для EXE и DLL. Поэтому такой код приведет к ошибке:

test_dll.dll:
Код

class CSome
{
public:
CSome() {}
virtual ~CSome() {}
};

typedef CSome* LPSOME;

extern "C" __declspec(dllexport) LPSOME Some()
{
return new CSome;
}



test.exe:
Код

class CSome
{
public:
CSome() {}
virtual ~CSome() {}
};

typedef CSome* LPSOME;

BOOL CTest_exeApp::InitInstance()
{
HMODULE hmod=LoadLibrary("test_dll.dll");
LPSOME (*pfn)() = (LPSOME (*)())GetProcAddress(hmod, "Some");
LPSOME ob=(*pfn)();
FreeLibrary(hmod);
delete ob; // будет EXCEPTION !!!!!!!!!!!!!!!!!!
return FALSE;
}


А вот если поубирать "virtual" у деструкторов в EXE и в DLL - все будет Ok, т.к. физическое расположение функции CSome::~CSome будет в EXE (а не в DLL, как в приведенном примере).

Если у кого-то появятся похожие траблы - пишите !


--------------------
user posted image
PM MAIL WWW   Вверх
SMILic
Дата 16.4.2004, 22:11 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











привет, ты в паскале шариш??? biggrin.gif
Добавлено @ 22:15
эй мне просто помощь нужна а я здесь впервые, вот и не знаю куда потикнутся ??? посодействуй хоть крапаль, хотя бы ради солидарности baaa.gif
  Вверх
Fantasist
Дата 16.4.2004, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



На самом деле есть еще такая фигня, как менеджер памяти. То есть для выделения куска памяти new может обращатся к встроенному менеджеру памяти (как и delete для освобождения), который для dll и для exe может быть своим. Тут все зависит от реализации RTL. В Делфи происходит именно таким образом, поэтому менеджеры памяти существуют и в dll и в exe, поэтому там принципиально нельзя освобождать память выделенную в другом модуле, используя встроенный менеджер памяти. Правда там его тоже можно достадочно легко подменить и сделать его разделяемым.

А вообще, идейно это не правильно. Память должна освобождаться там же, где и была выделенна.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
mr.DUDA
Дата 17.4.2004, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



SMILic, я конечно рад помочь, но:
1) для этого вовсе не обязательно поднимать на форуме тему, созданную почти год назад, существует такая вещь как ПМ
2) по "паскалю" помогут товарищи, сидящие на форуме по Delphi

Fantasist, в целом согласен, но вот какая фигня: создаётся ли при линковке DLL отдельный блок функций CRT, или используется тот, что и в EXE, подгрузившей данную DLL ?... В общем-то, суть оригинального вопроса была и не в этом, а в том, что когда DLL выгружается - соответственно все функции, в т.ч. и виртуальные методы классов - становятся недоступны, отчего генерируется исключение в случае вызова виртуального деструктора объекта, динамически созданного в DLL.

Думаю, что на этом можно тему и закрыть, всем спасибо за ответы.


--------------------
user posted image
PM MAIL WWW   Вверх
  
Закрытая темаСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1119 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.