Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Dll и освобождение памяти

9.8K
09 апреля 2006 года
lifer
27 / / 30.03.2006
У меня имеется dll, в которой находятся глобальные хуки (обработка мыши, клавы и т.д.),
т.е. эта dll отображается в адресное пространство всех процессов.
Далее. В ней есть какая-то функция (не хук) char* f(...){...}, возвращающая указатель на строку. В теле этой функции строка создается так:
char *s=new char[...];
Далее в нее заносятся данные, и происходит воврат:
return s;
Насколько я знаю, у dll нет собственной кучи, и память для s выделяется в куче процесса, в пространство которого отобразилась dll. Вооот...
Далее. У меня есть сервис, использующий хуки в dll, в нем установлен таймер и в обработчике события от таймера прописан вызов функции f().
Самое интересное. Если я правильно понимаю, то раз, скажем, в минуту у меня вызывается f() из адресного пространства моего(??) сервиса, и в его куче каждый раз выделяется память для s?
Чтобы избежать утечки памяти, я в сервисе после использования возвращенного функцией f() указателя p использую delete p;
В итоге, когда происходит вызов f() по таймеру, появляется месаджбокс, где написано, что ошибка в visual'овском файле dbgheap.c на такой-то строчке.
Вообщем там в комментариях написано, что указатель должен находится в локальной куче, чтобы его можно было удалить.
Так вот. Если dll использует кучу моего сервиса, то я не понимаю, в чем проблема. Если же dll использует кучу процесса, в котором сработал хук, то я из своего сервиса вообще не могу получить доступ к куче другого процесса (по крайней мере так люди пишут).
Вопрос в том, как же мне освободить память, выделяемую для строки s после ее использования?
406
09 апреля 2006 года
vitaly2003s
481 / / 27.07.2004
Вот что пишет Рихтер по этому поводу:

Важно понимать, что единое адресное пространство состоит из одного исполняемого модуля и нескольких DLL-модулей. Одни из них могут быть скомпонованы со статически подключаемой библиотекой С/С++, другие — с DLL-версией той же библиотеки, а третьи (написанные нс на С/С++) вообще ею не пользуются Многие разработчики допускают ошибку, забывая, что в одном адресном пространстве может одновременно находиться несколько библиотек С/С++. Взгляните на этот код:

VOID EXEFunc()
{

PVOID pv = DLLFunc();

// обращаемся к памяти, на которую указывает pv;
// предполагаем, что pv находится в С/С++-куче ЕХЕ-файла

free(pv);

}

PVOID DLLFunc()
{

// выделяем блок в С/С++-куче DLL return(malloo(100));

}

Ну и что Вы думаете? Будет ли этот код правильно работать? Освободит ли ЕХЕ-функция блок, выделенный DLL-функцией? Ответы на все вопросы одинаковы- может быть Для точных ответов информации слишком мало. Если оба модуля (EXE и DLL) скомпонованы с DLL-версией библиотеки С/С++, код будет работать совершенно нормально. По ссли хотя бы один из модулей связан со статической библиотекой С/С++, вызов free окажется неудачным. Я нс раз видел, как разработчики обжигались на подобном коде.

На самом деле проблема, решается очень просто, ссли в модуле есть функция, выделяющая память, в нем обязательно должна быть и противоположная функция, которая освобождает память. Давайте-ка перепишем предыдущий код так:

VOID EXEFunc()
{

PVOID pv = DLLFunc();
// обращаемся к памяти, на которую указывает pv, // не делаем никаких предположений по поводу С/С++-кучи DLLFreeFunc(pv);

}

PVOID DllLFunc()
{

// выделяем блок в С/С++-кую DLL
PVOID pv = malloc(100); return(pv);

}

BOOL DLLFreeFunc(PVOID pv)
{

// освобождаем блок, выделенный в С/С++-куче OLL
return(free(pv));

}

Этот код будет работать при любых обстоятельствах Создавая свой модуль, не забывайте, что функции других модулей могут быть написаны па других языках, а значит, и ничего нс знать о malloc и free. Не стройте свой код на подобных допущениях. Кстати, то же относится и к С++-опсраторам new и delete, реализованным с использованием malloc frее
9.8K
10 апреля 2006 года
lifer
27 / / 30.03.2006
Спасибо за ответ! Как раз то, что надо! Я разобрался, и все заработало :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог