Как я могу освободить последний элемент массива в C ?

#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 ?

  1. Выделите новый массив, емкость которого на единицу меньше.
  2. Скопируйте все элементы, кроме последнего, во вновь созданный массив.
  3. Удалите исходный массив.

Пример:

 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();