2011-01-19 3 views
2

Можно ли отрастить памяти, выделенная operator new(), когда выделяются так:Восстановить память, выделенную оператором new()?

char* buf = new char[60]; 

В C++ FAQ говорится, что память, выделенная new не может быть изменена путем перераспределить, так что правильный способ отрастить память, выделенную new?

+1

Не существует аналогичной операции с 'realloc' с системой' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' по умолчанию ''. Если вам нужно использовать 'new', вы, вероятно, действительно хотите' std :: vector'. Дубликат: http://stackoverflow.com/questions/1179669/realloc-function-that-would-work-for-memory-allocated-using-new-instead-of-reallo – birryree

+0

Основываясь на [этом вопросе] (http: //stackoverflow.com/questions/1179669/realloc-function-that-would-work-for-memory-allocated-using-new-instead-of-reallo) не существует. – BlackBear

ответ

5

Правильный путь заключается в использовании std::vector или std::string в зависимости от конкретного использования массива - пусть C++ обрабатывать распределения для вас.

Если вы должны использовать new, вам придется перераспределять и копировать память. Эта простая шаблонная функция показывает вам основу:

template <typename T> 
T *GrowArray(T *oldArray, size_t oldCount, size_t newCount) { 
    T *newArray = new T[newCount]; 
    if (oldArray) { 
     std::copy(oldArray, oldArray + std::min(oldCount, newCount), newArray); 
     delete[] oldArray; 
    } 
    return newArray; 
} 

Обратите внимание, что в большинстве реализаций и в большинстве случаев использования, это, по существу, что делает realloc(), минус безопасность типа. Если это выглядит неэффективно для вас, хорошо, realloc(), вероятно, не делает ничего лучше.

+0

+1 для правильного решения с правильным (одним взглядом) кодом, но вызов этого метода 'GrowArray' немного вводит в заблуждение. Первоначальные указатели не хороши после вызова. –

+0

@John - ничто из соответствующей документации не может справиться. :) – James

+3

Ваш комментарий о 'realloc' на самом деле неверен. В то время как 'realloc' * может * делать что-то похожее на функцию, которую вы опубликовали, так же вероятно использовать специальные знания OS для« расширения »массива без копирования содержимого массива. Например, в некоторых версиях Linux блок памяти, возвращаемый 'malloc', добавляется с переменной размера, недоступной программисту, но доступной для внутренней реализации. Когда вызывается 'realloc', реализация может проверить эту переменную, чтобы увидеть, возможно ли расширить массив без копирования всего. –

6

Правильный способ - не делать этого.

Просто выделите новую память, если предыдущее распределение было недостаточно большим.

Или используйте std::vector, который очень эффективно обертывает все эти функции.

1

Единственный способ это сделать второй новый, скопируйте содержимое, а затем удалить старый блок памяти:

char *tmpbuff = new char[70]; 
memcpy(tmpbuff, buff, 60 * sizeof(char)); 
delete [] buff; 
buff = tmpbuff; 

(Нет ... C++ не является равным STL, так что есть жизнь без STL :-))

Смежные вопросы