#c #arrays #integer
#c #массивы #целое число
Вопрос:
У меня есть динамически выделяемый массив, подобный этому: a[1,2,3,*unallocated value*]
который имеет 4 элемента. У меня также есть length
переменная, из которой я знаю, какой она длины.
Я хочу удалить последний элемент в этом массиве и установить для него значение нераспределенный или каким-то образом неинициализировать его.
Я думаю, что что-то подобное может сработать a[lenght-1]=*something-something*
, но я не знаю, что поставить в конце. Есть ли способ отменить выделение одного элемента? Или я должен создать новый массив и скопировать в него все элементы, кроме последнего?
Заранее спасибо.
Комментарии:
1. Почему бы не использовать a
std::vector
? Вы можете выделить место для 4 целых чисел, но в векторе будет только три, пока вы не будете готовы добавить четвертый элемент. Пример того, зачем вам это нужно, может дать вам лучшую справку / ответы.2. Я бы также рекомендовал рекомендовать использовать std::vector для этого. Что было бы:
std::vector<int> a {1, 2, 3};
создать его с тремя элементами,a.push_back(4)
добавить4
к нему,a.pop_back()
освободить последний элементa.size()
для его текущего размера.3. Если вы хотите придерживаться использования массивов (я не рекомендую), я полагаю, вам придется создать новый массив и скопировать в него все элементы, кроме последнего (что незначительно увеличивает производительность, вам лучше просто использовать вектор или уменьшить переменную размера).
4. @ColonD Это для школьного упражнения, и мы еще не изучали векторы, поэтому, если я сделаю это таким образом, возможно, они его не примут. Но спасибо за ваши предложения. 🙂
Ответ №1:
Чтобы ответить на ваш вопрос:
Как я могу освободить последний элемент массива в C ?
- Выделите новый массив, емкость которого на единицу меньше.
- Скопируйте все элементы, кроме последнего, во вновь созданный массив.
- Удалите исходный массив.
Пример:
int *p_original_array = new int[5];
int *p_shorter_array = new int[4];
//...
std::copy(p_original_array, p_original_array 4, p_shorter_array);
delete [] p_original_array;
Ответ №2:
Вызывается *something-something*
искомый sentinel
элемент.
Например, если ваш массив может содержать только положительные целые числа, вы можете использовать значение 0
для указания «пустого» слота. Или -1
.
Однако, если разрешены КАКИЕ-либо целочисленные значения, это не сработает.
С другой стороны — зачем вам вообще нужно помещать какое-либо значение в этот слот? Вы можете просто полагаться на свою length
переменную, чтобы определить, является ли этот элемент допустимым или нет.
Ответ №3:
во-первых, вы всегда можете установить что-то в нулевой указатель. Но я думаю, что для вашего варианта использования вектор — это то, что вы хотите использовать. Вектор использует массив как структуру данных, но вы можете добавлять / удалять элементы в конце. (если векторное заполнение — это массив, он создаст больший массив и скопирует все, поэтому не нужно беспокоиться о длине)
Комментарии:
1. во-первых, вы всегда можете установить что-то в нулевой указатель , нет, вы не можете. Только указатели могут быть установлены на
NULL
Ответ №4:
Неясно, хотите ли вы удалять элементы только по end или это может произойти в любой позиции.
В первом случае вы могли бы использовать переменную length для хранения «используемой длины», а другую переменную, возможно, с именем «емкость», для хранения фактической емкости вашего массива. Первый никогда не будет больше второго, но он может быть меньше. Это очень простое решение: если вы задаете размер 3, индекс 3 больше не используется, и вам больше нечего делать.
Во втором случае я бы предложил стратегию sentinel, которая описана в ответе @Vlad Feinstein.
Ответ №5:
Поскольку у вас есть length
указание количества допустимых элементов в массиве, нет необходимости копировать значения в новый массив. Просто уменьшите length
. В зависимости от типа данных, используемого в массиве, может иметь или не иметь смысла сбрасывать значение последнего элемента.
Например, на самом деле нет смысла вообще сбрасывать целое число, но вы можете, если хотите, например:
a[--lenght] = 0;
Но имеет смысл сбросить a std::string
, чтобы освободить любую динамическую память, которую он может использовать внутри, например:
a[--lenght] = "";
a[--lenght] = string();
--lenght;
a[lenght].clear();
a[length].shrink_to_fit();