DLL и выделение памяти
От: dlgv Украина  
Дата: 08.12.04 16:11
Оценка:
Привет, есть проблемка:
В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?

Благодарнейшее спасибо за ответы!

09.12.04 14:59: Перенесено модератором из 'C/C++' — Odi$$ey
Re: DLL и выделение памяти
От: Bell Россия  
Дата: 08.12.04 16:18
Оценка:
Здравствуйте, dlgv, Вы писали:

D>Привет, есть проблемка:

D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?

Выделенную внутри DLL память освобождать нужно. Но делать это нужно правильно.
Некоторые детали можно посмотреть здесь
Автор(ы): Роман Хациев
Дата: 27.02.2002
Если вы пытались работать с экземплярами классов STL, передавая их в DLL, или получая оттуда, а потом бросили это занятие из-за непонятных ошибок, возникающих в вашей программе, то эта заметка для вас. Даже если видимых проблем в вашей программе нет, то все равно прочитайте эту заметку, чтобы знать что делать, когда они появятся :)
Любите книгу — источник знаний (с) М.Горький
Re: DLL и выделение памяти
От: Sergey Россия  
Дата: 08.12.04 16:23
Оценка:
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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: DLL и выделение памяти
От: Croc Россия  
Дата: 08.12.04 18:37
Оценка:
Здравствуйте, dlgv, Вы писали:

D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?


Суть проблемы в том, что операторы new/delete могут различаться в разных модулях (в приложении и dll в данном конкретном случае). Если Вы работаете с объектами STL, то выше Вам дали ссылку, многое разъясняющую.

Если речь о Ваших собственных массивах или объектах, то самое типичное, но что можно сразу "нарваться" в MSVC6 — это сообщение что-то вроде InvalidHeapAddress в дебагерной версии (хотя если Вы работаете с незамысловатыми данными, то в Release все может и обойтись).

Один из более-менее универсальных способов решения проблемы — освобождать память в том же модуле, где ее выделяли. Можно:
1) Экспортировать отдельную функцию из DLL для освобождения данного объекта (массива и т.д.).
2) Использовать для уничтожения объекта виртуальную функцию.

Главное, не волнуйтесь! То что с Вами произошло совершенно типично
Просто спокойно устраните проблему.


Удачи.
Re: DLL и выделение памяти
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 09.12.04 04:24
Оценка:
Здравствуйте, dlgv, Вы писали:

D>Привет, есть проблемка:

D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?

Выделенную внутри DLL память освобождать обязательно, причём в самой же DLL, а не в вызывающем её модуле.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: DLL и выделение памяти
От: dlgv Украина  
Дата: 09.12.04 07:26
Оценка:
Спасибо за ответы!!! Да, если выделять и освобождать память в одном модуле,то все OK. Так и поступил
Re[2]: DLL и выделение памяти
От: rus blood Россия  
Дата: 09.12.04 09:29
Оценка:
Здравствуйте, dlgv, Вы писали:

D>Спасибо за ответы!!! Да, если выделять и освобождать память в одном модуле,то все OK. Так и поступил


template <class T>
class allocator
{
    typedef void* (__cdecl* malloc_t)(size_t);
    typedef void (__cdecl* free_t)(void*);
public:
    typedef T            value_type;
    typedef T*            pointer;
    typedef const T*    const_pointer;
    typedef T&            reference;
    typedef const T&    const_reference;
    typedef size_t        size_type;
    typedef ptrdiff_t    difference_type;

public:
    allocator() : 
        m_pfMalloc(&malloc), m_pfFree(&free) 
            {}
    allocator(const allocator<T>& _all) : 
        m_pfMalloc(_all.m_pfMalloc), m_pfFree(_all.m_pfFree) 
            {}
    template <class R>
    allocator(const allocator<R>& _all) : 
        m_pfMalloc(_all.m_pfMalloc), m_pfFree(_all.m_pfFree) 
            {}

    pointer adddress(reference _val) const
        { return &_val; }
    const_pointer address(const_reference _val) const
        { return &_val; }

    pointer allocate(size_type _size)
        { return (pointer)m_pfMalloc(_size); }
    template <class R>
    pointer allocate(size_type _size, const R*)
        { return (pointer)m_pfMalloc(_size); }

    void construct(pointer _ptr, const T& _val)
        { new((void*)_ptr) T(_val); }

    void deallocate(pointer _ptr, size_type)
        { m_pfFree(_ptr); }

    void destroy(pointer _ptr)
        { _ptr->~T(); }

    size_type max_size() const
        { return (size_type)(-1) / sizeof (T); }

    template<class R>
    struct rebind 
    {
        typedef allocator<R> other;
    };
    
public:
    malloc_t    m_pfMalloc;
    free_t        m_pfFree;
};
Имею скафандр — готов путешествовать!
Re: DLL и выделение памяти
От: Glоbus Украина  
Дата: 09.12.04 14:10
Оценка:
Здравствуйте, dlgv, Вы писали:

D>Привет, есть проблемка:

D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?

D>Благодарнейшее спасибо за ответы!


В данном случае освобождать память должен тот кто ее выделил. То есть нужно, чтобы сама длл-на контролировала когда удалять объект и осовбождать память
Удачи тебе, браток!
Re: DLL и выделение памяти
От: gwg-605 Россия  
Дата: 11.12.04 00:35
Оценка:
Здравствуйте, dlgv, Вы писали:

D>В функции в DLL выделяю память и возвращаю указатель на нее клиенту.При попытке клиента освободить эту память возникает ошибка. В чем проблема? Выделенную внутри DLL память освобождать необязательно?

Нет освобождать надо Я так понимаю проблема из-за статически прилинкованного CRT. Насколько я понимаю у тебя получается два "инстанса" CRT, один в DLL, другой в EXE. Обе они инициализируются и создают два хипа памяти, которые друг о друге ничего не знают Ты выделяешь память в одном хипе, а потом пытаешься освободить в другом — и получаешь ошибку

Варианты решения:
— динамически линковать CRT
— освобождать память в тоже модуле где она выделялась
— написать свой менеджер памяти (вместо стандартного)
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[2]: DLL и выделение памяти
От: Игорь Вартанов Ниоткуда  
Дата: 11.12.04 08:29
Оценка:
Здравствуйте, gwg-605, Вы писали:

G6>Здравствуйте, dlgv, Вы писали:


G6>Варианты решения:

G6>- динамически линковать CRT
G6>- освобождать память в тоже модуле где она выделялась
G6>- написать свой менеджер памяти (вместо стандартного)

Почему-то сишноплюсовые ребята стесняются пользовать нативные виндовые способы работы с памятью, все им поддержку от рантайма хочется поюзать.
А второй+третий вариант уже реализован в винде и выглядит как

GlobalAlloc — GlobalFree
LocalAlloc — LocalFree
HeapAlloc — HeapFree

Если от кода не требуется переносимость && по некоторым соображениям динамическая CRT противопоказана && но выделенную память нужно удалять в клиенте, то вышеуказанные методы лечения, имхо, самые достойные.
---
С уважением,
Игорь
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.