Как вы 'realloc' в C++?


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

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

4 64

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, вероятно, будет просто a 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() вектор), разрешенный, но не определено, разрешено, но зависит от реализации или запрещено.

вопрос, который вы должны затем задать себе: "действительно ли полезно предоставить это, учитывая, что vector также делает это и специально разработан для обеспечения контейнера с возможностью изменения размера (непрерывной памяти-это требование опущено в C++98, но исправлено в C++03), который лучше подходит, чем массивы с способами выполнения C++?"

я думаю, что ответ широко считается "нет". Если вы хотите сделать изменяемого размера буфера с пути, используйте malloc / free / realloc, которые доступны в C++. Если вы хотите сделать изменяемые размеры буферов способом C++, используйте вектор (или deque, если вам на самом деле не нужно непрерывное хранение). Не пытайтесь смешать их с помощью new[] для необработанных буферов, если вы не реализуете вектор - подобный контейнер.

попробуйте что-то вроде этого:

typedef struct Board
{
    string name;
    int size = 0;
};

typedef struct tagRDATA
{
    vector <Board> myBoards(255);

    // Board DataBoard[255];
    int SelectedBoard;

} RUNDATA;

вектор будет жаловаться. Вот почему массивы, malloc и new все еще существуют.