От: | Rakafon | http://rakafon.blogspot.com/ | |
Дата: | 29.07.09 00:56 | ||
Оценка: |
Важно понимать, что единое адресное пространство состоит из одного исполняемого модуля и нескольких DLL-модулей. Одни из них могут быть скомпонованы со статически подключаемой библиотекой С/C++, другие — с DLL-версией той же библиотеки, а третьи (написанные не на С/C++) вообще ею не пользуются. Многие разработчики допускают ошибку, забывая, что в одном адресном пространстве может одновременно находиться несколько библиотек С/C++. Взгляните на этот код:
VOID EXEFunc() { PVOID pv = DLLFunc(); // обращаемся к памяти, на которую указывает pv; // предполагаем, что pv находится в С/C++-куче EXE-файла free(pv); } PVOID DLLFunc() { // выделяем блок в С/C++-куче DLL return(malloc(100)); }
Ну и что Вы думаете? Будет ли этот код правильно работать? Освободит ли EXE-функция блок, выделенный DLL-функцией? Ответы на все вопросы одинаковы — может быть. Для точных ответов информации слишком мало. Если оба модуля (EXE и DLL) скомпонованы с DLL-версией библиотеки С/C++, код будет работать совершенно нормально. По если хотя бы один из модулей связан со статической библиотекой С/C++, вызов free окажется неудачным. Я не раз видел, как разработчики обжигались на подобном коде.
На самом деле проблема, решается очень просто, если в модуле есть функция, выделяющая память, в нем обязательно должна быть и противоположная функция, которая освобождает память. Давайте-ка перепишем предыдущий код так:
VOID EXEFunc() { PVOID pv = DLLFunc(); // обращаемся к памяти, на которую указывает pv, // не делаем никаких предположений по поводу С/C++-кучи DLLFreeFunc(pv); } PVOID DllFunc() { // выделяем блок в С/C++-куче DLL PVOID pv = malloc(100); return(pv); } BOOL DLLFreeFunc(PVOID pv) { // освобождаем блок, выделенный в С/C++-куче DLL return(free(pv)); }
Этот код будет работать при любых обстоятельствах. Создавая свой модуль, не забывайте, что функции других модулей могут быть написаны на других языках, а значит, и ничего не знать о malloc и free. Не стройте свой код на подобных допущениях. Кстати, то же относится и к C++-операторам new и delete, реализованным с использованием malloc — free.