a tutorial on ‘dynamic’ arrays in C
For the purposes of education and the prospect of writing a new game, I’ve been doing some poking around in C. I’ve certainly learned a few things (and expect to learn more in the future) Prior to this, I’ve only had experience with C++, which some would argue is a completely different beast altogether. However, this post is not intended to discuss the differences between C and C++.
Anyways, I figured I might share a few snippets and wisdom that I’ve picked up along the way, so here’s a quick (?) rundown of how to use structs and pointers to create “dynamic” arrays that will resize as you need them.
Right, so let’s suppose you’ve got a struct built that you’ll use to hold some data…
typedef struct {
char *name;
int number;
} DATA;
And we’ll also need to set up an array, along with some variables to track how many items are in the array and how large the array is…
DATA *TheArray; int numElements = 0; // keep track of the number of elements used int numAllocated = 0; // essentially how large the array is
What’s this? I’m not using []’s to define the size of the array? That’s right. At this point, the array is uninitialized and currently just a pointer. We’ll need to allocate memory for each entry into the array.
So next, we need a way to add items to our array that will be mindful of the fact that it is dynamic. What is needed is a function that will do three things:
- Initialize the array if it is not already initialized.
- Resize the array if more space is needed.
- Add new items to the array.
Keeping that in mind, let’s take a look at the realloc function’s prototype:
void * realloc ( void * ptr, size_t size );
The purpose of this function is to re-allocate memory to a pointer that already has memory allocated to it. Of course, you’ll only want to use it to make memory allocations larger, otherwise you’ll risk losing data. The size parameter is the amount of memory that you want to allocate. And the other parameter, ptr, is where you’d like to allocate it to. In this case, it’ll be the TheArray pointer that we’ve defined above. What is great about realloc is that if the ptr is NULL, the function will act just like malloc. This will allow us to use this one call for both initializing and resizing the array. Check this realloc reference page for more information.
Here is the AddToArray function …
void AddToArray (DATA item)
{
if(numElements == numAllocated) // need more refs?
{
if (numAllocated == 0)
numAllocated = 3; // start off with 3 refs
else
numAllocated *= 2; // double the refs allocated
TheArray = (DATA*)realloc(TheArray, (numAllocated * sizeof(DATA)));
if (TheArray == NULL)
{
fprintf(stdout, "ERROR: Couldn't realloc memory!");
exit(2);
}
}
TheArray[numElements] = item;
numElements++;
return;
}
You can see that it performs all three requirements listed above.
You may ask, ‘why is the allocation size doubling each time a resize is needed?’. This is done mainly because realloc() can be an expensive call, and if you spend a lot of time resizing your array, it could slow down the execution of your application. This way, it’s only done once in a while. Of course, feel free to fiddle with the initial allocation as well.
Also, be careful when using realloc(), as you’ll need to remember to use the free() function later on to free the memory that you’ve allocated to your program. You’ll want to run this code when you’re done using the array …
// Deallocate! free(TheArray);
I’ve got a little example available right here:
Download Example - (arrays.c - 1.78kb)
It compiles and runs just fine using GCC, but I haven’t tried it with anything else, so your mileage may vary. Also, a huge special thanks to DrPetter and X-0ut for their help on this subject!
As always, comments are welcome!

Sorry if this is a dumb question but why would “TheArray” ever be NULL?
if (TheArray == NULL)
{
fprintf(stdout, “ERROR: Couldn’t realloc memory!”);
exit(2);
}
Sorry for not adding this into my first reply, but how do you deallocate each item in the array if you do not know the size of the array?
Hi Anthony! Thanks for the comments.
I probably should have elaborated a little more in the article, but if there is insufficient memory available, the realloc() call will return NULL. Since you don’t have any control over how much free memory the user will have available, it’s a good idea to check to ensure the allocation succeeded.
As for your second question, in my example I’ve created two variables that will track the number of elements in the array, as well as the number of elements allocated in the array. You actually don’t even need those variables for deallocation, as just passing the array to the free() function will automatically deallocate the entire array.
Hope that helps!
thx for the tutorial it helped alot.
amazing!
I’ve learned about realloc.
@7
Your code has two flaws, and since you’re the number one Google entry under ‘C dynamic array’, I feel moved to comment.
First,
When ‘realloc’ returns NULL, the input data is not freed. Thus, you’ve written a memory leak (at least, you would if the error case wasn’t ‘exit()’). It’s more common to use a metaphor like this:
void *_tmp = realloc(TheArray, newsize);
if (!_tmp) { fprintf(stderr,”whoa, dude, no memory\n”); return(-1); }
TheArray = _tmp;
thus your structure contains the data before the failed add, thus can be used if the addition isn’t fatal, and a ‘free’ of the object is uncomplicated.
Second, TheArray is uninitialized. If you’re programming in Linux, ‘valgrind’ is a huge tool here, other analysis tools like Purify are available for other platforms.
Hi this tutorial is highly helpful and very lucid