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
🌐
Swarthmore College
cs.swarthmore.edu › ~newhall › unixhelp › C_arrays.html
Arrays in C
C has support for single and multidimensional arrays. Arrays can be statically allocated or dynamically allocated.
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_dynamic_arrays.htm
Dynamic Arrays in C
In this example, we dynamically allocate memory based on the size entered by the user. After allocation, we assign values to each element of the array and then display them. For example, if the user enters 5, the program allocates memory for 5 integers and stores the values 1, 2, 3, 4, 5. Enter size of elements:5 Memory successfully allocated using malloc. The elements of the array are: 1, 2, 3, 4, 5, The "calloc" method, commonly known as the "contiguous allocation" method in C, dynamically allocates the requested number of memory blocks of the specified type and initializes each block with a default block 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!

🌐
GeeksforGeeks
geeksforgeeks.org › c language › dynamic-array-in-c
Dynamic Array in C - GeeksforGeeks
July 23, 2025 - Array in C is static in nature, so its size should be known at compile time and we can't change the size of the array after its declaration. Due to this, we may encounter situations where our array doesn't have enough space left for required elements or we allotted more than the required memory leading to memory wastage. To solve this problem, dynamic arrays come into the picture.
🌐
Scaler
scaler.com › home › topics › dynamic array in c
Dynamic Array in C - Scaler Topics
August 24, 2023 - They also generate much more Assembly ... be: ... Unlike other high-level languages (Python, JavaScript, etc), C doesn't have built-in dynamic arrays....
🌐
Quora
quora.com › How-do-you-create-a-dynamic-array-of-structures-in-the-C-programming-language-What-is-the-use-of-it
How to create a dynamic array of structures in the C programming language? What is the use of it - Quora
It doesn’t matter what data type the array is, you just have to specify how large the chunk of memory you want is to be. And that uses the compiler “sizeof” operator to get the size of whatever a data type is, then multiply by the number of elements. The “calloc”, and “reallocarray” functions actu ... How do you create a dynamic array of structures in the C programming language?
🌐
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 problem with VLAs is that one cannot change the size of the array after initialization (which is variable), eventually causing the same problem as the one faced while using stack arrays. This is where dynamic arrays allow users to create arrays that can be varied at runtime, unlike the fixed-length/variable-length arrays.
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.
🌐
DEV Community
dev.to › godinhojoao › dynamic-arrays-in-c-l86
Dynamic Arrays in C - DEV Community
August 4, 2025 - An array that can grow or shrink in size during runtime. Unlike static arrays, which have a fixed size, dynamic arrays automatically resize as elements are added or removed.
🌐
Reddit
reddit.com › r/c_programming › working with dynamic arrays in c
r/C_Programming on Reddit: Working with dynamic arrays in C
February 4, 2024 -

Hi there! How do C programmers work with dynamically allocated arrays – i.e vectors as in std::vector – in real C codebases, where dynamic allocations are possible (that is, there is heap memory and enough memory etc.)?

I keep finding myself wanting to do something like: struct vec { int* ptr; size_t len, cap; } and a bunch of other functions to create such a vector, push to it etc. If I were not to do this, I'd have to pass to many functions int** ptr, size_t* len, size_t* cap, which is very cumbersome.

None of the two methods above feel very C-like, given that there is no proper metaprogramming and that this approach seems like a too hefty abstraction for C but again, I don't have experience with real codebases, production code. In some situations I find that I can reduce the number of parameters, but not all.

What do you think? What is the solution? Do you have other approaches? Have you encountered this? If not, why?

Thank you very much for your input!

P.S. On mobile. If code formatting is broken, I'll fix it later. Also, the C23 changes which add some kind of generics using macros should not affect the answers here, as far as I can think; this question is in its essence concerned with abstraction in C and how it is approached in C.

Top answer
1 of 4
8
You’ll get a ton of different answers to this question because there is no standardized approach. The standardized approach arrived with C++ and std::vector. None of the two methods above feel very C-like […] You’ll see plenty of code like struct vec { int *data; size_t len, cap; }; This, at least, is clear and easy to understand. Any C programmer will look at this and immediately understand (or guess) that it’s a dynamic array. The only real question is how you work with it. Some people use macros. Either a bunch of macros to define all sorts of helper functions, or a small number of macros that you call directly. Some of these macros work on structures, some can work directly on variables stored anywhere. You can find examples in the Git codebase. Here’s one of them (line 1156): https://github.com/git/git/blob/2a540e432fe5dff3cfa9d3bf7ca56db2ad12ebb9/git-compat-util.h#L1156 Some people don’t use macros, and just use a small number of helper functions, or code that is copy-pasted. My advice? Keep it simple. Don’t go wild with the preprocessor. If you start doing lots of different tricks with the preprocessor, you can end up with C that is unreadable and hard to debug or analyze. Some amount of duplication is to be expected in a C codebase—use your own judgment, and try to keep your code simple.
2 of 4
6
Generally speaking, try to make the caller responsible for memory management. This allows them to use auto, static, or allocated storage as they like. Instead of forcing them to use allocated storage and the reallocating it, you can just fail and inform them of how much memory would be required to succeed. This is how the standard library operates, and snprintf is a reasonable example of the approach.
🌐
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.
🌐
Emory
cs.emory.edu › ~cheung › Courses › 255 › Syllabus › 2-C-adv-data › dyn-array.html
Dynamic arrays in C
Do-it-yourself dynamic array in C · The C programming language does not have dynamic array as a language feature
🌐
Lautarojayat
lautarojayat.github.io › data-structures-and-algorithms-in-c › 03_dynamc_array
Implementing a dynamic array | An overview of data structures and algorithms in C
An overview of data structures and algorithms in C · Dynamic arrays are similar to static arrays in the sense that they allow easy reading, insertion, or modification of elements by referring to them using their index within the array.
🌐
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 - Dynamic Arrays in C Understanding array manipulation is fundamental for software engineers. A dynamic array is an array that can automatically resize itself when its capacity is exceeded. This is …
🌐
Medium
medium.com › @bassettjosh397 › building-a-dynamic-array-from-first-principles-in-c-512fae478da7
Building a Dynamic Array From First Principles In C | by Josh Bassett | Medium
April 30, 2025 - First we reallocate the size of the array by one. Then we set the data type value of the new element. Then we perform a check for the new elements data type. If it is a string, we copy the value into the new address. Check the length, if it is greater than 0, set the previous to the length -1 and next to -1 for the null terminator. Otherwise set the previous to -1 as the null terminator. Increment the length. ... What we are essentially achieving is the dynamic increase of the size of the array in memory, as shown above.
🌐
Quora
quora.com › How-can-I-create-a-dynamic-array-in-the-programming-language-C
How to create a dynamic array in the programming language C - Quora
Answer (1 of 5): You can create a dynamic array by using malloc function. example: If you want to create an integer array size 10, you can use int *arr=(int *)malloc(sizeof(int)*10) For future reference you refer to the link below. C Memory Allocation Using malloc(), calloc(), free() & realloc()
🌐
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 ...
🌐
GitHub
github.com › eignnx › dynarray
GitHub - eignnx/dynarray: A generic dynamic array implementation in C. · GitHub
A generic dynamic array implementation in C. A dynarray of type T can be passed to any function that operates on vanilla T arrays.
Author   eignnx