Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > realloc() или свой вариант?


Автор: andrew_121 25.3.2009, 10:45
Доброго времени суток.
Есть шаблонный объект, который является оберткой типа массива, со своим менеджментом памяти.
В нем есть такой код отвечающий за выделения памяти.
Код

bool up_resize( luint32 len ) {
    luint32 new_cnt = EXPONENT_UP( _capacity, len );
    if ( new_cnt > _capacity ) {
        if ( _begin != NULL ) {
            _begin = (type*)realloc( _begin, sizeof(type)*new_cnt );
            if ( _begin == NULL ) {
                throw std::bad_alloc();
                _end = NULL;
                return false;
            }
        } else {
            _begin = new type[new_cnt+1];
            if ( _begin == NULL ) {
                throw std::bad_alloc();
                _end = NULL;
                return false;
            }
        }
        _capacity = new_cnt;
    }
    _end = _begin + len;
}

Есть сомнение в правильности работы realloc(). Так как при хранении некоторых типов объектов, при вызове realloc() происходит глюк.

Вопрос: На сколько правильно использование realloc() совместно с new?

Автор: Gradov 25.3.2009, 11:32
Никогда не экспериментировал в использовании new совместно с malloc,realloc для работы с одним и тем же участком памяти. И мне кажется ничего хорошего из этого не выйдет!  smile 

Либо malloc, realloc, либо new.

Автор: andrew_121 25.3.2009, 19:41
Предложите свои варианты реализации сей функции.

Автор: baldina 25.3.2009, 20:11
Цитата

_begin = new type[new_cnt+1];

здесь вызывается конструктор type()
Цитата

_begin = (type*)realloc( _begin, sizeof(type)*new_cnt );

здесь - нет. потому и глюк. но это в слабом предположении, что new/delete реализованы через malloc/free
а вообще-то по стандарту куча и свободная память - не одно и то же и смешивать malloc и new нельзя

Цитата

Предложите свои варианты 

std::vector. особо пытливые могут написать для него свой allocator smile 

Автор: zim22 25.3.2009, 20:18
andrew_121, тут написано, что думает Страуструп по поводу мешанины С и С++ функций работы с памятью
http://www.research.att.com/~bs/bs_faq2.html#realloc

а здесь Hamrick предлагает свой вариант решения проблемы
http://www.daniweb.com/forums/showthread.php?t=84974&highlight=realloc+vs+new

Автор: andrew_121 26.3.2009, 11:31
Цитата(baldina @  25.3.2009,  20:11 Найти цитируемый пост)
здесь вызывается конструктор type()

 smile Как я мог этого не заметить...?  smile 
zim22, Спасибо!

Автор: sparn 28.3.2009, 18:18
В Си++ есть такая конструкция: 
Код

T *new (T *ptr) T;

По сути это всего лишь корректное конструирование объекта на уже выделенном участке памяти, выделенном любым аллокатором. Подобным образом можно вызвать любой конструктор в том числе и копирования, например:
Код

CDog *MyDog = new (ptr) CDog(ParentDog);

Так что если вы используете malloc, realloc или другие менеджеры памяти и хотите корректного конструирования объектов то это то что вам нужно. Ну и соответственно вызывайте деструкторы.

Цитата

Код

_begin = new type[new_cnt+1];


Думаю стоит заметить что в данном случае все объекты будут инициализированы конструктором по умолчанию и следовательно будет нетривиально корректно перекопировать старые объекты в новый участок памяти путём вызова конструктора копирования. В общем, если задача копировать старые объекты не стоит то можно использовать и такую конструкцию.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)