I can use pointers, but I am a bit afraid of using them.

If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.

If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)

typedef struct {
  int *array;
  size_t used;
  size_t size;
} Array;

void initArray(Array *a, size_t initialSize) {
  a->array = malloc(initialSize * sizeof(int));
  a->used = 0;
  a->size = initialSize;
}

void insertArray(Array *a, int element) {
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size 
  if (a->used == a->size) {
    a->size *= 2;
    a->array = realloc(a->array, a->size * sizeof(int));
  }
  a->array[a->used++] = element;
}

void freeArray(Array *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

Using it is just as simple:

Array a;
int i;

initArray(&a, 5);  // initially 5 elements
for (i = 0; i < 100; i++)
  insertArray(&a, i);  // automatically resizes as necessary
printf("%d\n", a.array[9]);  // print 10th element
printf("%d\n", a.used);  // print number of elements
freeArray(&a);
Answer from casablanca on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › c language › dynamic-array-in-c
Dynamic Array in C - GeeksforGeeks
July 23, 2025 - The elements of the array are: 1, 2, 3, 4, 5, The “calloc” or “contiguous allocation” method in C is used to dynamically allocate the specified number of blocks of memory of the specified type and initialized each block with a default value of 0...
Top answer
1 of 11
314

I can use pointers, but I am a bit afraid of using them.

If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.

If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)

typedef struct {
  int *array;
  size_t used;
  size_t size;
} Array;

void initArray(Array *a, size_t initialSize) {
  a->array = malloc(initialSize * sizeof(int));
  a->used = 0;
  a->size = initialSize;
}

void insertArray(Array *a, int element) {
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size 
  if (a->used == a->size) {
    a->size *= 2;
    a->array = realloc(a->array, a->size * sizeof(int));
  }
  a->array[a->used++] = element;
}

void freeArray(Array *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

Using it is just as simple:

Array a;
int i;

initArray(&a, 5);  // initially 5 elements
for (i = 0; i < 100; i++)
  insertArray(&a, i);  // automatically resizes as necessary
printf("%d\n", a.array[9]);  // print 10th element
printf("%d\n", a.used);  // print number of elements
freeArray(&a);
2 of 11
34

One simple solution involves mmap. This is great if you can tolerate a POSIX solution. Just map a whole page and guard against overflows, since realloc would fail for such values anyway. Modern OSes won't commit to the whole lot until you use it, and you can truncate files if you want.

Alternatively, there's realloc. As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.

Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.

Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...

Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...

... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.

malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.

It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(

When you define your struct, declare your array at the end of the structure, without any upper bound. For example:

struct int_list {
    size_t size;
    int value[];
};

This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!

sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.

Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:

int push_back(struct int_list **fubar, int value) {
    size_t x = *fubar ? fubar[0]->size : 0
         , y = x + 1;

    if ((x & y) == 0) {
        void *temp = realloc(*fubar, sizeof **fubar
                                   + (x + y) * sizeof fubar[0]->value[0]);
        if (!temp) { return 1; }
        *fubar = temp; // or, if you like, `fubar[0] = temp;`
    }

    fubar[0]->value[x] = value;
    fubar[0]->size = y;
    return 0;
}

struct int_list *array = NULL;

The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...

array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:

struct int_list *array = NULL;
if (!push_back(&array, 42)) {
    // success!
}

P.S. Remember to free(array); when you're done with it!

Discussions

"Correct" way of doing dynamically allocated multidimensional arrays in C
The second way is standard. The indexing is hard initially but I’ve gotten used to it. Also it gives the best performance generally for whatever most people are trying to do. More on reddit.com
🌐 r/C_Programming
39
72
January 2, 2022
c - Using Dynamic Memory allocation for arrays - Stack Overflow
For example here is the following ... save them word by word in the array: ... Here 1000 defines the number of words the array can save and each word may comprise of not more than 15 characters. Now I want that that program should dynamically allocate the memory for the number ... More on stackoverflow.com
🌐 stackoverflow.com
Is my understanding of dynamically allocating arrays in C correct?
No, this is not accurate. First of all, each function doesn't have its own stack. I think you meant to talk about the size of the function's stack frame. The stack frame doesn't have to have a fixed size that's known at compile time, because the compiler can generate code to push and pop things onto the stack as necessary. And in fact, there is nothing stopping you from declaring a dynamically-sized array on the stack in C (this was added in the C99 language specification). Some actual reasons to use dynamic allocation instead of stack allocation might be: The stack generally has a limited size compared to the heap, so a large array might not fit You might want the array to continue existing after the function that created it has returned More on reddit.com
🌐 r/learnprogramming
7
1
October 20, 2022
difference between Dynamic Array VS. Dynamically Allocated Array ?
A dynamic array is a data structure. It is similar to an array, but its size automatically grows when you add a new element to it, and it is already full. So if you had a dynamic array of size 10, and it already had 10 elements in it, then adding another would automatically grow the array and add the new element. A dynamic array can be created on the stack or on the heap. A dynamically allocated array is a (normal) array created on the heap. Since it is on the heap it will continue to exist even outside the original scope in which it was declared (at least in C++). More on reddit.com
🌐 r/learnprogramming
8
2
January 8, 2017
🌐
Swarthmore College
cs.swarthmore.edu › ~newhall › unixhelp › C_arrays.html
Arrays in C
To dynamically allocate space, use calls to malloc passing in the total number of bytes to allocate (always use the sizeof to get the size of a specific type). A single call to malloc allocates a contiguous chunk of heap space of the passed size. ... // declare a pointer variable to point to ...
🌐
Reddit
reddit.com › r/c_programming › "correct" way of doing dynamically allocated multidimensional arrays in c
r/C_Programming on Reddit: "Correct" way of doing dynamically allocated multidimensional arrays in C
January 2, 2022 -

There are 3 ways that I know of to dynamically allocate a multidimensional array in C:

1- The malloc -> malloc -> malloc... way

int x = 4, y = 5;
int** arr = malloc(sizeof(*arr) * x);
for (int i = 0; i < x; ++i) {
    arr[i] = malloc(sizeof(arr[0]) * y);
}

This seems to be the worst method of them all. It's verbose to create and free and generates fragmented memory blocks. Also gets progressively bigger the more dimensions there are.

2- The 1D array with indexing way

int index(int x, int y, int maxX)
{
    return y * maxX + x;
}

int main(void)
{
    int x = 4, y = 5;
    int* arr = malloc(sizeof(*arr) * x * y);
    // get element at position (0, 2)
    int elem = arr[index(0, 2, x)];
}

This is better but not much. Having to call index every time you access the array is a pain. You would also need to create a index function for each number of dimensions.

2.1- The indexing way with a macro

#define ARR(X, Y) arr[Y * x + X]

int main(void)
{
    int x = 4, y = 5;
    int* arr = malloc(sizeof(*arr) * x * y);
    // get element at position (0, 2)
    int elem = ARR(0, 2);
}

I guess you could consider this better, but I personally don't really like it. Also has the same problems that number 2 has.

3- The VLA way

int x = 4, y = 5, z = 10, w = 2;
int (*arr2D)[y] = malloc(sizeof(int[x][y]));
int (*arr3D)[y][z] = malloc(sizeof(int[x][y][z]));
int (*arr4D)[y][z][w] = malloc(sizeof(int[x][y][z][w]));

This really looks like the perfect solution. Easy to adapt to any number of dimensions and easy to index. The only downside I could find is that VLA support is not required since C11, but I'm not sure if any big compiler doesn't support them.

So, is number 3 really the best way of doing it by a far margin? Or are there any downsides to it that I don't know of? What is the method you would use on some real world project?

🌐
Medium
medium.com › @sohaib.arshid101 › dynamic-arrays-in-c-an-implementation-guide-4a959de94332
Dynamic arrays in C: An implementation guide | by curious&dumb | Medium
March 5, 2024 - The macro was responsible for checking ... of the array by twice the current ArrSize. realloc(void* ptr, size_t size) attempts to resize the memory block pointed to by ptr that was previously allocated with a call to malloc or calloc. Keep in mind that realloc() can also fail, which is why safety checks are important. The accompanying dynamic_array.c file ...
🌐
Scaler
scaler.com › home › topics › dynamic array in c
Dynamic Array in C - Scaler Topics
August 24, 2023 - Dynamic arrays are resizable and provide random access for their elements. They can be initialized with variable size, and their size can be modified later in the program. Dynamic arrays are allocated on the heap, whereas VLAs are allocated ...
Find elsewhere
🌐
Codecademy
codecademy.com › docs › arrays › dynamic arrays
C | Arrays | Dynamic Arrays | Codecademy
January 30, 2025 - A dynamic array in C refers to an array whose size can be adjusted during runtime. Unlike static arrays, whose size must be fixed at compile time, dynamic arrays offer flexibility by utilizing memory allocation functions from the stdlib.h library, ...
🌐
Medium
medium.com › @pauljlucas › dynamically-allocating-2d-arrays-efficiently-and-correctly-in-c-2-0-ee2087c98960
Dynamically Allocating 2D Arrays Efficiently (and Correctly!) in C 2.0 | by Paul J. Lucas | Medium
January 22, 2026 - If you want to allocate an m × n 2D matrix, you can much more simply do: int (*const a)[n] = malloc( m * n * sizeof(int) ); a[i][j] = 42; // works free( a ); where a is a constant pointer to an array of n integers. Although it’s using variable length array (VLA) syntax, it’s not allocating a VLA on the stack since malloc is being used.
🌐
Programiz
programiz.com › c-programming › c-dynamic-memory-allocation
C Dynamic Memory Allocation Using malloc(), calloc(), free ...
Sometimes the size of the array you declared may be insufficient. To solve this issue, you can allocate memory manually during run-time. This is known as dynamic memory allocation in C programming.
🌐
Medium
medium.com › @nick-stambaugh › dynamic-arrays-in-c-fdc8a2f66b53
Dynamic Arrays in C. Understanding array manipulation is… | by Nick Stambaugh | Medium
May 4, 2024 - The C function malloc allows us to dynamically allocate memory for our DynamicArray. By taking the sizeof our DynamicArray , we can fetch the number of elements in our array.
🌐
Emory
cs.emory.edu › ~cheung › Courses › 255 › Syllabus › 2-C-adv-data › dyn-array.html
Dynamic arrays in C
dynamic array (of any data type): The calloc() function: memory allocation function for arrays · Fact: To · allocate memory cells for · N consecutive variable (= array), you must use this function: The calloc function: Example: dynamic array · We have now learn ·
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › how-to-dynamically-allocate-an-array-in-cpp
How to Dynamically Allocate an Array in C++? - GeeksforGeeks
July 23, 2025 - In C++, dynamic memory allocation allows us to allocate memory during runtime. Dynamic allocation in an array is particularly useful when the size of an array is not known at compile time and needs to be specified during runtime.
🌐
PrepBytes
prepbytes.com › home › c programming › dynamic array in c
Dynamic Array in C
June 19, 2023 - Variable length arrays, also known as dynamic arrays, in C have their size determined at runtime (although the size cannot be modified after initialization). These arrays were first introduced in the C99 standard but became an optional feature in subsequent versions. Similar to normal arrays, dynamic arrays allocated on the stack are released when they go out of scope...
🌐
Bytesbeneath
bytesbeneath.com › p › dynamic-arrays-in-c
Dynamic Arrays in C - by Dylan Falconer - Bytes Beneath
January 18, 2024 - You could have the allocator provide a realloc function so you dont have to handle the realloc logic in `array_ensure_capacity`. Would make it easy to provide the C stdlib realloc function instead of handling the logic here. All that logic could be boiled down to just this: const size_t new_size = sizeof(ListPrelude) + new_capacity * item_size; prelude = prelude->allocator->realloc(prelude, new_size); ... This article has been very educational thus far on how one could manage dynamic arrays in c.
🌐
Wikipedia
en.wikipedia.org › wiki › Dynamic_array
Dynamic array - Wikipedia
1 month ago - A simple dynamic array can be constructed by allocating an array of fixed-size, typically larger than the number of elements immediately required. The elements of the dynamic array are stored contiguously at the start of the underlying array, ...
Top answer
1 of 8
30

You use pointers.

Specifically, you use a pointer to an address, and using a standard c library function calls, you ask the operating system to expand the heap to allow you to store what you need to.

Now, it might refuse, which you will need to handle.

The next question becomes - how do you ask for a 2D array? Well, you ask for an array of pointers, and then expand each pointer.

As an example, consider this:

int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));

if ( words == NULL )
{
    /* we have a problem */
    printf("Error: out of memory.\n");
    return;
}

for ( i=0; i<num_words; i++ )
{
    words[i] = malloc((word_size+1)*sizeof(char));
    if ( words[i] == NULL )
    {
        /* problem */
        break;
    }
}

if ( i != num_words )
{
    /* it didn't allocate */
}

This gets you a two-dimensional array, where each element words[i] can have a different size, determinable at run time, just as the number of words is.

You will need to free() all of the resultant memory by looping over the array when you're done with it:

for ( i = 0; i < num_words; i++ )
{
    free(words[i]);
}

free(words);

If you don't, you'll create a memory leak.

You could also use calloc. The difference is in calling convention and effect - calloc initialises all the memory to 0 whereas malloc does not.

If you need to resize at runtime, use realloc.

  • Malloc
  • Calloc
  • Realloc
  • Free

Also, important, watch out for the word_size+1 that I have used. Strings in C are zero-terminated and this takes an extra character which you need to account for. To ensure I remember this, I usually set the size of the variable word_size to whatever the size of the word should be (the length of the string as I expect) and explicitly leave the +1 in the malloc for the zero. Then I know that the allocated buffer can take a string of word_size characters. Not doing this is also fine - I just do it because I like to explicitly account for the zero in an obvious way.

There is also a downside to this approach - I've explicitly seen this as a shipped bug recently. Notice I wrote (word_size+1)*sizeof(type) - imagine however that I had written word_size*sizeof(type)+1. For sizeof(type)=1 these are the same thing but Windows uses wchar_t very frequently - and in this case you'll reserve one byte for your last zero rather than two - and they are zero-terminated elements of type type, not single zero bytes. This means you'll overrun on read and write.  

Addendum: do it whichever way you like, just watch out for those zero terminators if you're going to pass the buffer to something that relies on them.

2 of 8
7

While Ninefingers provided an answer using an array of pointers , you can also use an array of arrays as long as the inner array's size is a constant expression. The code for this is simpler.

char (*words)[15]; // 'words' is pointer to char[15]
words = malloc (num_words * sizeof(char[15]);

// to access character i of word w
words[w][i];

free(words);
🌐
Florida State University
cs.fsu.edu › ~vastola › cop3014 › notes › dma.html
Dynamic Allocation
new int; // dynamically allocates an int new double; // dynamically allocates a double · If creating an array dynamically, use the same form, but put brackets with a size after the type:
🌐
University of Wollongong
documents.uow.edu.au › ~lukes › textbook › notes-cpp › newdelete › 50dynamalloc.html
C++ Notes: Dynamic Allocation of Arrays
A dynamically allocated array is declared as a pointer, and must not use the fixed array size declaration. The above declaration creates a pointer, but doesn't yet allocate any memory to it. When the desired size of an array is known, allocate memory for it with the new operator and save the ...
🌐
Reddit
reddit.com › r/learnprogramming › is my understanding of dynamically allocating arrays in c correct?
r/learnprogramming on Reddit: Is my understanding of dynamically allocating arrays in C correct?
October 20, 2022 -

I was going through an example of C code, and I was trying to figure out WHY we have to dynamically allocate an array rather than statically allocate in a specific example. I will write the example in pseudo code as it is simple and the code is not the point of this question:

  1. obtain user input using scanf method and store in variable of type int n

  2. Create an array int A[n]

Is my logic sound for why this is wrong:

This is wrong because the compiler has to decide the size of the function stack. In order to asses the size of the function stack, it will observe each of the variables in the function. However, since the value of n will only be determined at runtime, we cannot determine how much stack memory is needed for array A because the size will only be determined at run time. As a result, we must dynamically allocate memory.