Как я могу realloc
в C ++? Кажется, он отсутствует в языке - есть новые
и delete
, но нет resize
!
Мне это нужно, потому что, поскольку моя программа читает больше данных, Мне нужно перераспределить буфер для его хранения. Я не думаю, что удалить
старый указатель и новый
новый, больший, является правильным вариантом.
Используйте ::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, скорее всего, будет просто malloc
, 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 ()
вектор), разрешено, но не указано, разрешено, но зависит от реализации, или запрещено.
Тогда вам следует задать себе следующий вопрос: «Действительно ли полезно предоставлять это, учитывая, что вектор
также делает это и разработан специально для предоставления изменяемого размера контейнера (непрерывной памяти - -это требование опущено в C ++ 98, но исправлено в C ++ 03), что лучше подходит, чем массивы с методами работы C ++? »
Я думаю, что широко распространено мнение, что ответ -« нет ».Если вы хотите изменять размер буферов способом C, используйте malloc / free / realloc
, которые доступны в C ++. Если вы хотите изменять размер буферов, как в C ++, используйте вектор (или deque
, если вам действительно не нужно непрерывное хранилище). Не пытайтесь смешивать их, используя new []
для необработанных буферов, если только вы не реализуете векторный контейнер.