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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Аллокатор памяти и STL, как подменить на свой? 
:(
    Опции темы
SIRIUStar
  Дата 23.1.2009, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 20.7.2007
Где: Одинцово

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



Всем привет! У меня задачка появилась: Необходимо подменить стандартный аллокатор памяти allocator<type> на свой в STL. Я кое что накопал по этому поводу, но это не работает, во всяком случае правильно. Возникает ошибка в менеджере памяти, Но этого быть никак не может! Он проверенный и хорошо работает. Поэтому я думаю что не правильно наследовал, хотя все вроде делают так.. Можно было бы перегрузить new, но для меня это не выход, хотя с перегруженным new работает нормально) smile 

Код

#include <iostream>

#include <algorithm>
#include <cmath>
#include <string>

#include <vector>
#include <list>
#include <map>

#include "winnie_alloc.h"

using namespace std;

template<class usertype> class CNovaAlloc : public std::allocator<usertype>
{
public:

    template<class _Other> struct rebind
    {
        typedef CNovaAlloc<_Other> other;
    };

    template<class _Other> CNovaAlloc(const CNovaAlloc<_Other> & p) throw() { }

    template<class _Other> CNovaAlloc<usertype> & operator=(const CNovaAlloc<_Other> & p)
   {
        return (*this);
    }
    
    CNovaAlloc(const CNovaAlloc<usertype> & p) throw() {}

    CNovaAlloc() throw() {}

    ~CNovaAlloc() throw() {}

    allocator<usertype>::pointer allocate(allocator<usertype>::size_type n)
    { 
        void * p = Winnie::Alloc(n);
        return reinterpret_cast<pointer>(p);
    }

    void deallocate(allocator<usertype>::pointer p, allocator<usertype>::size_type n)
    { 
        Winnie::Free(p);
    }
};



Если кто знает как правильно наследовать аллокатор.. ну или какието другие решения, буду признателен.
PM MAIL WWW ICQ   Вверх
Lycifer
Дата 23.1.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



SIRIUStar - не когда не наследуйся от STL(разумеется кроме exception)
Алакатор свой вставляешь через шаблон(смотри сигнатуру используемого класса)
PM MAIL ICQ   Вверх
georain
Дата 23.1.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

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



SIRIUStar, что за ошибка?

Если Winnie::Alloc(n)  и Winnie::Free(n) заменить на обычные alloc и free работает?

Lycifer, почему нельзя от stl наследоваться?

PM MAIL   Вверх
Alek86
Дата 23.1.2009, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

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



Цитата(georain @  23.1.2009,  18:46 Найти цитируемый пост)
почему нельзя от stl наследоваться?

ибо у них не предусмотрено виртуальных деструкторов
правда слово "никогда" тут некстати, ибо иногда это делать можно


SIRIUStar, для подстановки аллокатора в экземпляр шаблона не обязательно наследовать - главное, чтоб в твоем классе были нужные функции.


--------------------
user posted image    user posted image
PM MAIL   Вверх
georain
Дата 23.1.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

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



Вот пример аллокатора, можно просто заменить Allocate и Free;

Код


// выделяет память
void* Allocate(size_t size);
// освобождает память
void Free(void * ptr, size_t size) throw();


// stl-совместимый аллокатор
template <typename T>
class Allocator{
public:

    typedef size_t        size_type;
    typedef ptrdiff_t    difference_type;
    typedef T*            pointer;
    typedef const T*    const_pointer;
    typedef T&            reference;
    typedef const T&    const_reference;
    typedef T            value_type;

    Allocator(){}
    Allocator(const Allocator&){}
    template <typename U>
    Allocator(const Allocator<U>&){}
    ~Allocator(){}

    template <typename U>
    struct rebind {
        typedef Allocator<U> other;
    };

    pointer address (reference value) const {
        return &value;
    }

    const_pointer address (const_reference value) const {
        return &value;
    }

    size_type max_size() const{
        return std::numeric_limits<size_t>::max() / sizeof(T);
    }

    pointer allocate(size_type num, const_pointer hint = 0){
        return static_cast<pointer>(Allocate(num*sizeof(T)));
    }

    void construct(pointer p, const_reference value){
        new((void*)p) T(value);
    }

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

    void deallocate(pointer p, size_type num){
        Free((void*)p, num*sizeof(T));
    }

}; // class Allocator

template<>
class Allocator<void>{
    public:

    typedef void*        pointer;
    typedef const void*    const_pointer;
    typedef void        value_type;

    template <class U>
    struct rebind{
        typedef Allocator<U> other;
    };
};


    template <class T1, class T2> inline
    bool operator== (const Allocator<T1>&, const Allocator<T2>){
        return true;
    }
    template <class T1, class T2> inline
    bool operator!= (const Allocator<T1>&, const Allocator<T2>){
        return false;
    }

PM MAIL   Вверх
SIRIUStar
  Дата 24.1.2009, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 20.7.2007
Где: Одинцово

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



SIRIUStar - не когда не наследуйся от STL(разумеется кроме exception)
Алакатор свой вставляешь через шаблон(смотри сигнатуру используемого класса)


Хм, чего не знал того не знал)) тоесть получется, что память забирается, но не освобождается при таком наследовании?

SIRIUStar, для подстановки аллокатора в экземпляр шаблона не обязательно наследовать - главное, чтоб в твоем классе были нужные функции.

это я понимаю.. но думал что от std::allocator наследоваться будет правильней)

Спасибо за примеры)) Да и кстате при замене аллокатора винни на связку malloc/free возникает ошибка Corruption Heap  smile (страшновато звучит) будем пробовать дальше)

Это сообщение отредактировал(а) SIRIUStar - 24.1.2009, 23:11
PM MAIL WWW ICQ   Вверх
georain
Дата 25.1.2009, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

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



SIRIUStar, попробуй использовать мой пример сначала с malloc/free, потом с винни, напиши что будет
PM MAIL   Вверх
Lazin
Дата 25.1.2009, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



SIRIUStar, просто убери из кода
Код

 : public std::allocator<usertype>

PM MAIL Skype GTalk   Вверх
SIRIUStar
  Дата 26.1.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 20.7.2007
Где: Одинцово

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



Всем спасибо) вопрос закрыт,  нашел у себя ошибку)
Дело в том, что метод allocate нужно реализовывать так:

Код

allocator<usertype>::pointer allocate(allocator<usertype>::size_type n)

        void *p = Winnie::Alloc(n * sizeof(usertype));

        return reinterpret_cast<pointer>(p);
}
// А у меня был просто
void *p = Winnie::Alloc(n);



Этот момент я упустил, без примеров бы долго тупил))  smile  smile 
PM MAIL WWW ICQ   Вверх
BasMan
Дата 14.3.2009, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Думаю создавать отдельную тему не стоит, поэтому задам вопрос тут smile

Существует приложение + плагины выполненные в виде dll/so библиотек, в приложении существует хост-объект, при инициализации библиотек им передается указатель на хост-объект (библы скомпилены с хидером в котором описаны все интерфейсы хоста и других предоставляемых приложением объектов, после получения указателя на хост, плагин от хоста получает указатель на фабрику объектов clsExecutorInterface, а затем регистрирует все доступные в плагине реализации clsExecutor, в дальнейнем, экземпляры зарегеных классов создаются в любом порядке. Строковые параметры в данный момент передаются как char*. Собственно это была преамбула, а теперь вопрос: если я заменю все char*на string (соответственно переписав необходимый и зависимый код), какой аллокатор памяти будет использоваться в экземплярах классов созданных на фабрике? Я думаю, что аллокатор из приложения, а не из библиотек, но все таки, кто может подсказать?
PM MAIL   Вверх
Lazin
Дата 14.3.2009, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



из библиотек, шаблоны инстанциируются во время компиляции
К.О.
PM MAIL Skype GTalk   Вверх
mes
Дата 14.3.2009, 20:25 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



не советовал бы использовать std::string (да и другие стл-типы)  для передачи параметров между библиотекой и приложением.


--------------------
PM MAIL WWW   Вверх
BasMan
Дата 14.3.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот поэтому и решил посоветоваться, т.к. вроде бы и библиотека, но объект создается на фабрике основного приложения, и все параметры передаются/принимаются уже этим объектом. Спасибо за информацию.
PM MAIL   Вверх
sparn
Дата 15.3.2009, 02:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

Репутация: нет
Всего: 1



Если память выделяется в приложении используется аллокатор приложения, если выделяется в библиотеке используется аллокатор библиотеки и они могут быть абсолютно разными, потому что модули могут быть скомпилированны различными компиляторами с различными настройками или использовать третьесторонние аллокаторы (Heap мэнеджер ОС Windows или такие как tcmalloc, horde и др.). Я думаю понятно что произойдёт если попытаться освободить память одним аллокатором выделенную на самом деле другим аллокатором. Отсюда следует золотое правило: освобождать память там где выделил. 
Если уж придётся передавать данные так что они должны будут освободиться в другом модуле то можно чтоб например приложение или библиотека предоставляла соответствующее API для выделения и освобождения памяти (это довольно общепринятая практика в больших библиотеках/модульных системах). Но динамическая подмена аллокаторов(чтоб использовать например в СТЛе аллокатор предоставляемый приложением) это отдельный изврат да и вообще редко когда осуществимо.
PM MAIL   Вверх
BasMan
Дата 15.3.2009, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Именно поэтому использовал с самого начала char*, просто точно не знал где выделяется память если объект создается на фабрике основного приложения (как я понял из постов выше, даже если объект создается на фабрике хоста, то память все равно выделяется в длл/со)

Это сообщение отредактировал(а) BasMan - 15.3.2009, 06:42
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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