Как вы перераспределяете в C ++?

Как я могу realloc в C ++? Кажется, он отсутствует в языке - есть новые и delete , но нет resize !

Мне это нужно, потому что, поскольку моя программа читает больше данных, Мне нужно перераспределить буфер для его хранения. Я не думаю, что удалить старый указатель и новый новый, больший, является правильным вариантом.

78
задан Jarvis 1 June 2017 в 09:07
поделиться

3 ответа

Используйте ::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-массив.

47
ответ дан 24 November 2019 в 10:38
поделиться

Правильный вариант - это использовать контейнер, который выполняет эту работу за вас, например std :: vector .

new и delete не могут изменить размер, потому что они выделяют достаточно памяти для хранения объекта данного типа. Размер данного типа никогда не изменится. Есть new [] и delete [] , но вряд ли когда-либо есть причина их использовать.

То, что realloc делает в C, скорее всего, будет просто malloc , memcpy и free в любом случае, хотя менеджеры памяти разрешено сделать что-нибудь умное, если имеется достаточно непрерывной свободной памяти.

45
ответ дан 24 November 2019 в 10:38
поделиться

Изменение размера в 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 [] для необработанных буферов, если только вы не реализуете векторный контейнер.

33
ответ дан 24 November 2019 в 10:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: