C ++ Удаление части динамического массива - PullRequest
8 голосов
/ 13 октября 2011

Скажем, у меня есть динамический массив вроде:

int* integers = new int[100];

Есть ли способ удалить только часть массива, такую ​​как:

int* integers2 = integers + 50;
delete[] integers2;

Я хочу не только удалить все 50 и более, но если я вызову еще один delete [] в исходном массиве целых чисел, он будет только удалять правильный объем памяти и не будет пытаться удалить первоначально выделенное количество и ошибку сегмента .

Почему я хочу это сделать: у меня есть структура данных, которая структурирована по уровням массивов, и я хочу иметь возможность создавать эту структуру данных из полного массива. Итак, я хочу иметь возможность сказать

int* level1 = integers;
int* level2 = integers + 50;
int* level3 = integers + 100;

Но когда уровень 3 больше не нужен, структура данных автоматически удалит [] уровень3. Мне нужно знать, что это будет вести себя правильно, а не просто уничтожить все в массиве. Если это произойдет, тогда мне нужно будет просто создать новые массивы и скопировать содержимое, но было бы неплохо избежать этого по соображениям производительности.

Редактировать: Кажется, все спешат с выводом, что я просто должен использовать контейнер динамического изменения размера (то есть vector, deque) в первую очередь для моей структуры данных. Я использую уровни массивов по уважительной причине (и они не одинакового размера, как я выгляжу, как в моем примере). Я просто искал хороший способ иметь конструктор для моей структуры данных, который бы содержал массив или вектор и не нуждался в копировании исходного содержимого в новую структуру данных.

Ответы [ 5 ]

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

Нет, это не будет вести себя правильно.Вы можете использовать только delete[] указатели, которые вы получили от new[], иначе результаты не определены и могут произойти плохие вещи.

Если вам действительно нужен массив, вам нужно выделить новый и скопироватьсодержимое вручную.

0 голосов
/ 13 октября 2011

Нет, вы не можете сделать это с массивом фиксированного размера, выделенным с new[]. Если вы хотите иметь динамический массив, используйте один из контейнеров STL, например std::vector.

0 голосов
/ 13 октября 2011

Динамические распределители (например, new) обычно не любят, когда вы освобождаете часть памяти, которую они вам дали.Если вы используете <malloc.h> определенные библиотечные функции malloc() и free() вместо new и delete, то вы можете использовать realloc(), хотя в большинстве случаев вам не безразлична разница в размере:в любом случае, чтобы скопировать для вас.

Контейнеры с динамическим размером обычно используют экспоненциальное правило для изменения размера: если вам не хватает места, они (например) удваивают распределение (и копируют старые данные), если вы удаляетеданные, пока вы не используете (например) менее половины выделения, они копируют в меньшее выделение.Это означает, что вы никогда не тратите больше половины памяти, а стоимость копирования для каждого добавленного или удаленного элемента практически постоянна.Реализация всего этого - боль в заднице, так что просто используйте std::vector и позвольте ей сделать это за вас:).

0 голосов
/ 13 октября 2011
int* integers2 = integers + 50;
delete[] integers2;

Не будет работать, потому что new создается на int *, поэтому целое число было присвоено пробелу 100 int, теперь integer2 является только указателем на 50-ю позицию целых чисел, у него нет своего собственного пробелапоэтому использование delete не приведет к удалению остатка целых чисел2, оно даст только ошибочные результаты.

Что вы можете сделать, это скопировать первые 50 в другом массиве и полностью удалить предыдущий массив.

delete удалит только указатель, которому назначен пробел, использование delete для другого указателя, указывающего на пробел, назначенный первому указателю, не удалит пробел, назначенный первому указателю.

delete [] inteers2 не будетудалить любой пробел, назначенный целым числам 1 или любому другому указателю.

0 голосов
/ 13 октября 2011

Как правило, когда память выделяется, перед указателем есть некоторые служебные данные.

т.е. данные хранения (указателя)

Вы запутаетесь.

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