Как вы 'realloc' в C++?
как я могу realloc
в C++? Кажется, его не хватает в языке-есть new
и delete
а не resize
!
мне это нужно, потому что, как моя программа читает больше данных, мне нужно перераспределить буфер для его хранения. Я не думаю delete
ing старый указатель и new
ing новый, больший, это правильный вариант.
4 ответа:
Use::std:: vector!
Type* t = (Type*)malloc(sizeof(Type)*n) memset(t, 0, sizeof(Type)*m)
становится
::std::vector<Type> t(n, 0);
затем
t = (Type*)realloc(t, sizeof(Type) * n2);
становится
t.resize(n2);
если вы хотите передать указатель в функцию, вместо
Foo(t)
использовать
Foo(&t[0])
это абсолютно правильный код C++, потому что vector-это умный c-массив.
правильный вариант, вероятно, использовать контейнер, который делает всю работу за вас, как
std::vector
.
new
иdelete
не может изменить, потому что они выделяют достаточно памяти для хранения объекта данного типа. Размер данного типа никогда не изменится. Естьnew[]
иdelete[]
но вряд ли когда-либо есть причина их использовать.что
realloc
делает в C, вероятно, будет просто amalloc
,memcpy
иfree
, во всяком случае, хотя менеджеры памяти разрешены чтобы сделать что-то умное, если есть достаточно смежной свободной памяти.
изменение размера в C++ неудобно из-за потенциальной необходимости вызова конструкторов и деструкторов.
я не думаю, что есть фундаментальная причина, почему в C++ вы не могли бы иметь
resize[]
оператора, чтобы пойти сnew[]
иdelete[]
, что сделали что-то похожее на это:newbuf = new Type[newsize]; std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf); delete[] oldbuf; return newbuf;
очевидно
oldsize
будет извлечен из секретного места, то же самое он находится вdelete[]
иType
будет исходить из типа операнда.resize[]
не где тип не копируется - что правильно, так как такие объекты просто не могут быть перемещены. Наконец, приведенный выше код по умолчанию-создает объекты перед их назначением, которые вы не хотели бы, как фактическое поведение.есть возможная оптимизация, где
newsize <= oldsize
, чтобы вызвать деструкторы для объектов "после конца" вновь захваченного массива и ничего больше не делать. Стандарт должен был бы определить, требуется ли эта оптимизация (например, когда выresize()
вектор), разрешенный, но не определено, разрешено, но зависит от реализации или запрещено.вопрос, который вы должны затем задать себе: "действительно ли полезно предоставить это, учитывая, что
vector
также делает это и специально разработан для обеспечения контейнера с возможностью изменения размера (непрерывной памяти-это требование опущено в C++98, но исправлено в C++03), который лучше подходит, чем массивы с способами выполнения C++?"я думаю, что ответ широко считается "нет". Если вы хотите сделать изменяемого размера буфера с пути, используйте
malloc / free / realloc
, которые доступны в C++. Если вы хотите сделать изменяемые размеры буферов способом C++, используйте вектор (илиdeque
, если вам на самом деле не нужно непрерывное хранение). Не пытайтесь смешать их с помощьюnew[]
для необработанных буферов, если вы не реализуете вектор - подобный контейнер.