Изменение размера массива с помощью C - PullRequest
19 голосов
/ 30 мая 2010

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

Может кто-нибудь показать мне, как это сделать?

Ответы [ 3 ]

29 голосов
/ 30 мая 2010

Начните с создания массива:

structName ** sarray = (structName **) malloc(0 * sizeof(structName *));

Всегда следите за размером отдельно:

size_t sarray_len = 0;

Чтобы увеличить или усечь:

sarray = (structName **) realloc(sarray, (sarray_len + offset) * sizeof(structName *));

Затем установите размер:

sarray_len += offset;

Рад помочь и надеюсь, что это поможет.

12 голосов
/ 07 октября 2014

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

Самая базовая форма:

// array initially empty
T *ptr = NULL;

// change the size of the array
ptr = realloc( ptr, new_element_count * sizeof *ptr );

if ( ptr == NULL )
{
    exit(EXIT_FAILURE);
}

Умножение объясняется тем, что realloc ожидает количество байтов, но вы всегда хотите, чтобы в вашем массиве было правильное количество элементов. Обратите внимание, что этот шаблон для realloc означает, что вам не нужно повторять T где-либо в вашем коде, кроме исходного объявления ptr.

Если вы хотите, чтобы ваша программа могла восстанавливаться после сбоя выделения вместо выполнения exit, вам нужно сохранить старый указатель вместо того, чтобы перезаписывать его NULL:

T *new = realloc( ptr, new_element_count * sizeof *ptr );

if ( new == NULL )
{
    // do some error handling; it is still safe to keep using
    // ptr with the old element count
}
else
{
    ptr = new;
}

Обратите внимание, что сжатие массива с помощью realloc может на самом деле не возвращать память операционной системе; память может по-прежнему принадлежать вашему процессу и доступна для будущих вызовов на malloc или realloc.

8 голосов
/ 30 мая 2010

С http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/

/* realloc example: rememb-o-matic */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  int input,n;
  int count=0;
  int * numbers = NULL;

  do {
     printf ("Enter an integer value (0 to end): ");
     scanf ("%d", &input);
     count++;
     numbers = (int*) realloc (numbers, count * sizeof(int));
     if (numbers==NULL)
       { puts ("Error (re)allocating memory"); exit (1); }
     numbers[count-1]=input;
  } while (input!=0);

  printf ("Numbers entered: ");
  for (n=0;n<count;n++) printf ("%d ",numbers[n]);
  free (numbers);

  return 0;
}
...