Есть ли способ расширить динамический массив памяти в C ++? - PullRequest
2 голосов
/ 06 октября 2011

Есть ли способ расширить массив динамической памяти? как это:

int *a = new int[5];
*a = new int[2];

Это законно?

Ответы [ 2 ]

9 голосов
/ 06 октября 2011

Вы не можете расширить этот тип массива динамической памяти.Вы можете использовать malloc и realloc, хотя, если вам нужна эта возможность, но я бы посоветовал против этого и предложил бы включить <vector> и вместо нее использовать std::vector.У него есть метод resize.

Кроме того, то, что вы описали, не скомпилируется.Следующее будет:

1: int *a = new int[5];
2: a = new int[2];

Выше будет выделено два блока памяти, ни один из которых не будет уничтожен.Вторая строка просто назначит новый массив тому же указателю int *a.Когда выделенная память перестает ссылаться на какой-либо указатель, это называется утечкой памяти.Приведенный выше код теряет любую ссылку на new int[5], и нет способа освободить эту память для операционной системы.

Хотя это не очень практичный пример, существует несколько способов изменить размер массива / вектора.Поскольку обычно практично увеличивать размер массива, я сделаю следующее:

{ // C++ vector on the stack (although internally vector uses memory from the heap)
    std::vector<int> a(1024);
    // do smth
    a.resize(4096); // note: this does not always reallocate
    // do smth else
}

{ // C++ everything on the heap
    std::vector<int> *a = new std::vector<int>(1024);
    // do smth
    a->resize(4096); // note: this does not always reallocate
    // do smth else
    delete a;
}

{ // C style
    int *a = (int*)malloc(1024*sizeof(int));
    // do smth
    a = realloc(a, 4096*sizeof(int));
    // do smth else
    free(a);
}

Стоит отметить, что realloc не делает ничего умного.Все, что он делает:

  • Выделение нового блока памяти malloc
  • Копирование данных из старого блока памяти в новый блок памяти memcpy
  • Свободный старый блок памятиfree
  • Возврат нового блока памяти
1 голос
/ 06 октября 2011

Вы можете , конечно, расширить массив, но вам нужно позаботиться о копировании содержимого и освобождении старого массива (ваш код, помимо неправильного синтаксиса, сокращает массив, кстати).

Именно так и работает std::vector, , просто вам не нужно заботиться .

Так что, в принципе, имея int *a уже выделено, что должно произойтиэто что-то вроде:

{
    std::unique_ptr<int[]> d(a);
    a = new int[desired_new_size];
    for(unsigned int i = 0; i < min_old_size_and_new_size; ++i)
        a[i] = d[i];
}

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

Вы должны никогда не использовать realloc (или любые другие функции выделения памяти C) в сочетании с выделенной памятью илиосвобожден operator new и delete (или new[] и delete[]), как указано выше.
Этот может работать (и обычно будет), но это концептуально неправильно, и это чистоудачи (неизвестные подробности реализации), если не произойдет сбой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...