Привет, есть проблемка:
В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
Благодарнейшее спасибо за ответы!
09.12.04 14:59: Перенесено модератором из 'C/C++' — Odi$$ey
Здравствуйте, dlgv, Вы писали:
D>Привет, есть проблемка: D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
Выделенную внутри DLL память освобождать нужно. Но делать это нужно правильно.
Некоторые детали можно посмотреть здесь
Hello, dlgv!
You wrote on Wed, 08 Dec 2004 16:11:56 GMT:
d> Привет, есть проблемка: d> В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При d> попытке клиента освободить эту память возникает ошибка. В чем проблема? d> Выделенную внутри DLL память освобождать необязательно?
Рантайм динамически линкуй, для начала.
With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 delta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, dlgv, Вы писали:
D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
Суть проблемы в том, что операторы new/delete могут различаться в разных модулях (в приложении и dll в данном конкретном случае). Если Вы работаете с объектами STL, то выше Вам дали ссылку, многое разъясняющую.
Если речь о Ваших собственных массивах или объектах, то самое типичное, но что можно сразу "нарваться" в MSVC6 — это сообщение что-то вроде InvalidHeapAddress в дебагерной версии (хотя если Вы работаете с незамысловатыми данными, то в Release все может и обойтись).
Один из более-менее универсальных способов решения проблемы — освобождать память в том же модуле, где ее выделяли. Можно:
1) Экспортировать отдельную функцию из DLL для освобождения данного объекта (массива и т.д.).
2) Использовать для уничтожения объекта виртуальную функцию.
Главное, не волнуйтесь! То что с Вами произошло совершенно типично
Просто спокойно устраните проблему.
Здравствуйте, dlgv, Вы писали:
D>Привет, есть проблемка: D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
Выделенную внутри DLL память освобождать обязательно, причём в самой же DLL, а не в вызывающем её модуле.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, dlgv, Вы писали:
D>Привет, есть проблемка: D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
D>Благодарнейшее спасибо за ответы!
В данном случае освобождать память должен тот кто ее выделил. То есть нужно, чтобы сама длл-на контролировала когда удалять объект и осовбождать память
Здравствуйте, dlgv, Вы писали:
D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?
Нет освобождать надо Я так понимаю проблема из-за статически прилинкованного CRT. Насколько я понимаю у тебя получается два "инстанса" CRT, один в DLL, другой в EXE. Обе они инициализируются и создают два хипа памяти, которые друг о друге ничего не знают Ты выделяешь память в одном хипе, а потом пытаешься освободить в другом — и получаешь ошибку
Варианты решения:
— динамически линковать CRT
— освобождать память в тоже модуле где она выделялась
— написать свой менеджер памяти (вместо стандартного)
Здравствуйте, gwg-605, Вы писали:
G6>Здравствуйте, dlgv, Вы писали:
G6>Варианты решения: G6>- динамически линковать CRT G6>- освобождать память в тоже модуле где она выделялась G6>- написать свой менеджер памяти (вместо стандартного)
Почему-то сишноплюсовые ребята стесняются пользовать нативные виндовые способы работы с памятью, все им поддержку от рантайма хочется поюзать.
А второй+третий вариант уже реализован в винде и выглядит как
Если от кода не требуется переносимость && по некоторым соображениям динамическая CRT противопоказана && но выделенную память нужно удалять в клиенте, то вышеуказанные методы лечения, имхо, самые достойные.