Resizing an array with C
Asked Answered
K

3

21

I need to have an array of structs in a game I'm making - but I don't want to limit the array to a fixed size. I'm told there is a way to use realloc to make the array bigger when it needs to, but can't find any working examples of this.

Could someone please show me how to do this?

Kaki answered 30/5, 2010 at 3:25 Comment(5)
Please post the code you have written so far. People generally do not like to just write your code for you.Debarath
For instance: Dynamic array of structs in C: #261415Debarath
How about the first google hit cplusplus.com/reference/clibrary/cstdlib/realloc ? What did you try so far?Addendum
I had good luck searching Google for realloc exampleHifalutin
See here for a more involved solution that wraps up the array with its lengthSubclavian
G
32

Start off by creating the array:

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

Always keep track of the size separately:

size_t sarray_len = 0;

To increase or truncate:

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

Then set the size:

sarray_len += offset;

Happy to help and hope that helps.

Glori answered 30/5, 2010 at 3:30 Comment(4)
The first line would be much improved by writing structName ** sarray = NULL; . It is well-defined to use realloc with a null pointer.Subclavian
Note that malloc(0) has implementation defined results; it may return NULL or a valid pointer that can never be dereferenced (but could be passed to free() or realloc()).Vookles
Nitpicking: This does not manage an "array of structs" but an array of pointers to structs.Uniform
Isn't this just the size of a pointer? sizeof(structName *) Isn't it sizeof(structName)? Also why do we need a double pointer?Demise
S
13

The realloc function can be used to grow or shrink an array. When the array grows, existing entries retain their value and new entries are uninitialized. This may either grow in-place, or if that was not possible, it may allocate a new block elsewhere in memory (and behind the scenes, copy all the values over to the new block and free the old block).

The most basic form is:

// 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);
}

The multiplication is because realloc expects a number of bytes, but you always want your array to have the right number of elements. Note that this pattern for realloc means you do not have to repeat T anywhere in your code other than the original declaration of ptr.

If you want your program to be able to recover from an allocation failure instead of doing exit then you need to retain the old pointer instead of overwriting it with 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;
}

Note that shrinking an array via realloc may not actually return memory to the operating system; the memory may continue to be owned by your process and available for future calls to malloc or realloc.

Subclavian answered 6/10, 2014 at 23:57 Comment(0)
C
11

From 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;
}
Cozart answered 30/5, 2010 at 3:29 Comment(1)
I gave reference, which makes it a cookie, no?Cozart

© 2022 - 2024 — McMap. All rights reserved.