The way you have it written now , used to be called the "struct hack", until C99 blessed it as a "flexible array member". The reason you're getting an error (probably anyway) is that it needs to be followed by a semicolon:

#include <stdlib.h>

struct my_struct {
    int n;
    char s[];
};

When you allocate space for this, you want to allocate the size of the struct plus the amount of space you want for the array:

struct my_struct *s = malloc(sizeof(struct my_struct) + 50);

In this case, the flexible array member is an array of char, and sizeof(char)==1, so you don't need to multiply by its size, but just like any other malloc you'd need to if it was an array of some other type:

struct dyn_array { 
    int size;
    int data[];
};

struct dyn_array* my_array = malloc(sizeof(struct dyn_array) + 100 * sizeof(int));

Edit: This gives a different result from changing the member to a pointer. In that case, you (normally) need two separate allocations, one for the struct itself, and one for the "extra" data to be pointed to by the pointer. Using a flexible array member you can allocate all the data in a single block.

Answer from Jerry Coffin on Stack Overflow
Top answer
1 of 9
90

The way you have it written now , used to be called the "struct hack", until C99 blessed it as a "flexible array member". The reason you're getting an error (probably anyway) is that it needs to be followed by a semicolon:

#include <stdlib.h>

struct my_struct {
    int n;
    char s[];
};

When you allocate space for this, you want to allocate the size of the struct plus the amount of space you want for the array:

struct my_struct *s = malloc(sizeof(struct my_struct) + 50);

In this case, the flexible array member is an array of char, and sizeof(char)==1, so you don't need to multiply by its size, but just like any other malloc you'd need to if it was an array of some other type:

struct dyn_array { 
    int size;
    int data[];
};

struct dyn_array* my_array = malloc(sizeof(struct dyn_array) + 100 * sizeof(int));

Edit: This gives a different result from changing the member to a pointer. In that case, you (normally) need two separate allocations, one for the struct itself, and one for the "extra" data to be pointed to by the pointer. Using a flexible array member you can allocate all the data in a single block.

2 of 9
28

You need to decide what it is you are trying to do first.


If you want to have a struct with a pointer to an [independent] array inside, you have to declare it as

struct my_struct { 
  int n; 
  char *s;
}; 

In this case you can create the actual struct object in any way you please (like an automatic variable, for example)

struct my_struct ms;

and then allocate the memory for the array independently

ms.s = malloc(50 * sizeof *ms.s);  

In fact, there's no general need to allocate the array memory dynamically

struct my_struct ms;
char s[50];

ms.s = s;

It all depends on what kind of lifetime you need from these objects. If your struct is automatic, then in most cases the array would also be automatic. If the struct object owns the array memory, there's simply no point in doing otherwise. If the struct itself is dynamic, then the array should also normally be dynamic.

Note that in this case you have two independent memory blocks: the struct and the array.


A completely different approach would be to use the "struct hack" idiom. In this case the array becomes an integral part of the struct. Both reside in a single block of memory. In C99 the struct would be declared as

struct my_struct { 
  int n; 
  char s[];
}; 

and to create an object you'd have to allocate the whole thing dynamically

struct my_struct *ms = malloc(sizeof *ms + 50 * sizeof *ms->s);

The size of memory block in this case is calculated to accommodate the struct members and the trailing array of run-time size.

Note that in this case you have no option to create such struct objects as static or automatic objects. Structs with flexible array members at the end can only be allocated dynamically in C.


Your assumption about pointer aritmetics being faster then arrays is absolutely incorrect. Arrays work through pointer arithmetics by definition, so they are basically the same. Moreover, a genuine array (not decayed to a pointer) is generally a bit faster than a pointer object. Pointer value has to be read from memory, while the array's location in memory is "known" (or "calculated") from the array object itself.

Top answer
1 of 10
44

You've tagged this as C++ as well as C.

If you're using C++ things are a lot easier. The standard template library has a template called vector which allows you to dynamically build up a list of objects.

#include <stdio.h>
#include <vector>

typedef std::vector<char*> words;

int main(int argc, char** argv) {

        words myWords;

        myWords.push_back("Hello");
        myWords.push_back("World");

        words::iterator iter;
        for (iter = myWords.begin(); iter != myWords.end(); ++iter) {
                printf("%s ", *iter);
        }

        return 0;
}

If you're using C things are a lot harder, yes malloc, realloc and free are the tools to help you. You might want to consider using a linked list data structure instead. These are generally easier to grow but don't facilitate random access as easily.

#include <stdio.h>
#include <stdlib.h>

typedef struct s_words {
        char* str;
        struct s_words* next;
} words;

words* create_words(char* word) {
        words* newWords = malloc(sizeof(words));
        if (NULL != newWords){
                newWords->str = word;
                newWords->next = NULL;
        }
        return newWords;
}

void delete_words(words* oldWords) {
        if (NULL != oldWords->next) {
                delete_words(oldWords->next);
        }
        free(oldWords);
}

words* add_word(words* wordList, char* word) {
        words* newWords = create_words(word);
        if (NULL != newWords) {
                newWords->next = wordList;
        }
        return newWords;
}

int main(int argc, char** argv) {

        words* myWords = create_words("Hello");
        myWords = add_word(myWords, "World");

        words* iter;
        for (iter = myWords; NULL != iter; iter = iter->next) {
                printf("%s ", iter->str);
        }
        delete_words(myWords);
        return 0;
}

Yikes, sorry for the worlds longest answer. So WRT to the "don't want to use a linked list comment":

#include <stdio.h>  
#include <stdlib.h>

typedef struct {
    char** words;
    size_t nWords;
    size_t size;
    size_t block_size;
} word_list;

word_list* create_word_list(size_t block_size) {
    word_list* pWordList = malloc(sizeof(word_list));
    if (NULL != pWordList) {
        pWordList->nWords = 0;
        pWordList->size = block_size;
        pWordList->block_size = block_size;
        pWordList->words = malloc(sizeof(char*)*block_size);
        if (NULL == pWordList->words) {
            free(pWordList);
            return NULL;    
        }
    }
    return pWordList;
}

void delete_word_list(word_list* pWordList) {
    free(pWordList->words);
    free(pWordList);
}

int add_word_to_word_list(word_list* pWordList, char* word) {
    size_t nWords = pWordList->nWords;
    if (nWords >= pWordList->size) {
        size_t newSize = pWordList->size + pWordList->block_size;
        void* newWords = realloc(pWordList->words, sizeof(char*)*newSize); 
        if (NULL == newWords) {
            return 0;
        } else {    
            pWordList->size = newSize;
            pWordList->words = (char**)newWords;
        }

    }

    pWordList->words[nWords] = word;
    ++pWordList->nWords;


    return 1;
}

char** word_list_start(word_list* pWordList) {
        return pWordList->words;
}

char** word_list_end(word_list* pWordList) {
        return &pWordList->words[pWordList->nWords];
}

int main(int argc, char** argv) {

        word_list* myWords = create_word_list(2);
        add_word_to_word_list(myWords, "Hello");
        add_word_to_word_list(myWords, "World");
        add_word_to_word_list(myWords, "Goodbye");

        char** iter;
        for (iter = word_list_start(myWords); iter != word_list_end(myWords); ++iter) {
                printf("%s ", *iter);
        }

        delete_word_list(myWords);

        return 0;
}
2 of 10
14

If you want to dynamically allocate arrays, you can use malloc from stdlib.h.

If you want to allocate an array of 100 elements using your words struct, try the following:

words* array = (words*)malloc(sizeof(words) * 100);

The size of the memory that you want to allocate is passed into malloc and then it will return a pointer of type void (void*). In most cases you'll probably want to cast it to the pointer type you desire, which in this case is words*.

The sizeof keyword is used here to find out the size of the words struct, then that size is multiplied by the number of elements you want to allocate.

Once you are done, be sure to use free() to free up the heap memory you used in order to prevent memory leaks:

free(array);

If you want to change the size of the allocated array, you can try to use realloc as others have mentioned, but keep in mind that if you do many reallocs you may end up fragmenting the memory. If you want to dynamically resize the array in order to keep a low memory footprint for your program, it may be better to not do too many reallocs.

Discussions

Best practice on allocating memory for a struct that has dynamic array members
Right now, the for loop is always printing the same value. You also need to free(ms->my_arr); Every malloc will have a corresponding free. More on reddit.com
🌐 r/C_Programming
21
3
February 29, 2024
Dynamic array size for structs?
I strongly recommend against the usage of flexible array members. I would do something like this: struct StructX { int* array; int w; int h; }; struct StructX* 2d_array_create(int w, int h) { struct StructX* p = malloc(sizeof(*p)); if (!p) { return NULL; } p->array = malloc(w * h * sizeof(int)); if (!p->array) { free(p); return NULL; } return p; } EDIT: They are actually called "flexible array members" not VLAS. See here More on reddit.com
🌐 r/C_Programming
13
7
January 27, 2020
Create dynamic array in struct
First off, i strongly recommend that you write C++ like C++ and not like C. If you are not from a C background, throw away the learning resource you are using and run (this is not an exaggeration). Instead use www.learncpp.com . Your problem is that newSet->arr = new int(member); constructs a single integer with value member and not an array. Hence any array access to it afterwards is UB. Further, in your insert function, you use Set::i, but it is not initialized. More UB. Finally, you fail to clean up setA in main. A better approach would be Use std::vector: int main() { std::vector setA; setA.push_back(5); setA.push_back(5); setA.push_back(5); setA.push_back(5); for ( const auto value : setA ) { std::cout << value << '\n'; } } or even better std::vector setA = { 5,5,5,5 }; Write it yourself, but actually write C++, i.e. use member functions, constructors and destructors: struct Set { int capacity = 0; int used_capacity = 0; int* arr = nullptr; Set( const int capacity ) //constructor : capacity( capacity ), arr( new int[capacity] ) //member initializer list {} ~Set() //destructor { delete[] arr; //cleans up the resource } void insert( int value ) { if ( used_capacity < capacity ) //check if there actually is space left { arr[ used_capacity++ ] = value; } } void print() { for ( int i=0; i < used_capacity; ++i ) { std::cout << arr[i] << '\n'; } } }; int main() { Set setA( 4 ); //dont use `new` if you dont have to. setA.insert( 5 ); setA.insert( 5 ); setA.insert( 5 ); setA.insert( 5 ); setA.print(); } //no need to call any `delete` because the destructor does it for you More on reddit.com
🌐 r/cpp_questions
6
0
April 18, 2021
dynamic array of structs in C - Stack Overflow
I am trying to learn about structs, pointers, and dynamic arrays in C. I don't understand how to create a dynamic array of structs using pointers. My code doesn't work, and I don't know what's wron... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-create-dynamic-array-of-structs-in-c
How to Create a Dynamic Array of Structs? - GeeksforGeeks
July 23, 2025 - A dynamic array of structs in C combines dynamic arrays and structures to organize and store multiple pieces of related information, each being implemented as a structure.
🌐
Reddit
reddit.com › r/c_programming › best practice on allocating memory for a struct that has dynamic array members
r/C_Programming on Reddit: Best practice on allocating memory for a struct that has dynamic array members
February 29, 2024 -

Hi all! I am very new to C but am familiar with Python & Go quite a bit. Memory allocation is a new concept to me, but I want to start with best practices.

Lets say I want to create a struct that has some members, where one of them happens to be a pointer which I will size dynamically as an array.

Here is what I am doing in my init_my_struct(int n) function. I want to understand if I am doing something that is bad practice here

#include <stdlib.h>
#include <stdio.h>

struct my_struct {
        int n;
        int *my_arr; // this will be dynamically grown based on user arg
};

struct my_struct * init_my_struct(int n)
{
        // allocate memory for one struct
        struct my_struct *ms = malloc(sizeof(struct my_struct));
        
        // use -> syntax since ms is a pointer
        ms->n = n;
        ms->my_arr = malloc(sizeof(int)*n);
        return ms;
}

int main(int argc, char *argv[])
{
        if (argc < 2) return 1;

        int n = atoi(argv[1]);
        
        // initialize the struct members
        struct my_struct *ms = init_my_struct(n);
        
        // check out contents of my struct
        printf("my struct's n: %d\n", ms->n);
        printf("my struct's my_arr: \n");
        for (int i = 0; i < n; i++) {
                printf("%d\n", ms->my_arr[i]);
        }
        free(ms); // clean up the memory

        return 0;
}

Any pointers or tips would be great! Thank you!

🌐
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
Interoperability: many C APIs expect contiguous arrays and lengths; dynamic arrays let you satisfy those interfaces. Simpler memory model than linked lists when frequent random access is needed. Enables collection resizing (grow, shrink, sort) without fixed compile-time limits. ... Use linked lists if frequent insert/remove in middle with minimal reallocation and pointer cost is acceptable. Use flexible storage (array of pointers to heap objects) if struct instances vary a lot in size or need polymorphic behavior.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 118221-dynamic-array-struct.html
dynamic array in STRUCT
It might be months before the bug is noticed, and weeks more before it's finally tracked down and fixed. Hi Salem, great hints; thanks so much Best regards, cfd ... Don't ever try to allocate anything being in a struct block. And if you use array notation [] in there, it shouldn't be empty.
🌐
Quora
quora.com › How-do-you-dynamically-allocate-an-array-of-struct-pointers-in-C
How to dynamically allocate an array of struct pointers in C - Quora
Answer (1 of 5): To dynamically allocate memory for pointer to array of struct you have to: * Create a pointer to pointer to the struct. * Then for example into a loop, allocate memory for any array member.
Find elsewhere
Top answer
1 of 3
1
Reference: pointers - How to include a dynamic array INSIDE a struct in C? - Stack Overflow[^] Putting what's there here for quick view: · C++ · #includestruct my_struct { · int n; · char s[]; · }; · When you allocate space for this, you want to allocate the size of the struct plus the amount of space you want for the array: · struct my_struct *s = malloc(sizeof( my_struct) + 50); · In this case, the flexible array member is an array of char, and sizeof(char)==1, so you don't need to multiply by its size, but just like any other malloc you'd need to if it was an array of some other type: · struct dyn_array { · int size; · data[]; · }; · · dyn_array* my_array = malloc(sizeof( dyn_array) + 100 * )); · There are more discussions on web for it.
2 of 3
0
On the rare occasions I must use calloc and free I like to use two helpful macros : · C++ · // allocate memory of a given type - must use free to release it · #define AllocateMemory(count,type) (type*)calloc(count,sizeof(type)) · // free an object and null it · #define ReleaseMemory(ptr) { if(ptr) { free(ptr); ptr=nullptr; } } · I always use calloc because it zeros the memory also so it saves a step. I use the macros because I think they make the code more clear and eliminate a cast. Here is a sample of them in use - allocating an array of integers. · int * integerArray = NULL; · integerArray = AllocateMemory( 1024, ); · · // do something with the array here · · ReleaseMemory( integerArray ); · It is very important to always release any memory that you allocate. When you don't it results in a memory leak and those are a very bad thing. If you write software that has to run for months and months leaks can cause crashes and those are very, very bad.
🌐
Dummies
dummies.com › article › technology › programming-web-design › cplusplus › using-a-dynamic-array-with-a-structure-150987
Using a Dynamic Array with a Structure | dummies
July 2, 2025 - #include <iostream> #include <new> using namespace std; struct Employee { string Name; int Age; }; int main() { Employee* DynArray; DynArray = new (nothrow) Employee[3]; DynArray[0].Name = "Harvey"; DynArray[0].Age = 33; DynArray[1].Name = "Sally"; DynArray[1].Age = 26; DynArray[2].Name = "Jeff"; DynArray[2].Age = 52; cout << "Displaying the Array Content" << endl; for (int i = 0; i < 3; i++) { cout << "Name: " << DynArray[i].Name << "tAge: " << DynArray[i].Age << endl; } delete[] DynArray; return 0; } In this example, the code begins by creating an Employee struct that contains the employee name and age. You could use any sort of data container desired — this one just happens to be a struct. In order to create a dynamic array, you define a pointer to the array variable.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-dynamically-create-array-of-structs-in-c
How to Dynamically Create Array of Structs in C? - GeeksforGeeks
July 23, 2025 - We then use typecasting to cast this pointer to the desired type which here is the pointer to struct. ... // C program to dynamically create array of structs #include <stdio.h> #include <stdlib.h> struct Student { int id; char name[50]; }; int main() { // Decalre the size of array int size = 5; // Initialize an array of structs struct Student* myArray = (struct Student*)malloc( size * sizeof(struct Student)); if (myArray == NULL) { fprintf(stderr, "Memory allocation failed\n"); return 1; } // Intialize data to structs present in the array for (int i = 0; i < size; i++) { myArray[i].id = i + 1; snprintf(myArray[i].name, sizeof(myArray[i].name), "Student%d", i + 1); } // Print the data of structs present in the array printf("Array Elements:\n"); for (int i = 0; i < size; i++) { printf("Element %d: ID = %d, Name = %s\n", i + 1, myArray[i].id, myArray[i].name); } free(myArray); return 0; }
🌐
Reddit
reddit.com › r/cpp_questions › create dynamic array in struct
r/cpp_questions on Reddit: Create dynamic array in struct
April 18, 2021 -

I have just recently started learning c++ and wad doing random exercises. In this problem, I want to dynamically create an array and assign it values using typedef and struct. Can someone guide me why am I getting garbage value on my object in init function? This might be a newbie question but I would really appreciate your guidance

    #include <iostream>
    typedef struct Set
    {
        int j;
        int i;
        int* arr;
    } Set;
    Set* init(int member);
    void insert(Set* set, int member);
    void print_set(Set* set);
    int main()
    {
        Set* setA = init(4);
        insert(setA, 5);
        insert(setA, 6);
        insert(setA, 7);
        insert(setA, 7);
        print_set(setA);
        delete[] setA->arr;
    }
    Set* init(int member)
    {
        Set* newSet = new Set;
        newSet->j = member;
        newSet->arr = new int(member);
        return newSet;
    }
    void insert(Set* set, int member)
    {
        set->arr[set->i] = member;
        set->i++;
    }
    void print_set(Set* set)
    {
        for (int j = 0; j < set->j; j++)
        {
            std::cout << set->arr[j] << endl;
        }
    }
Top answer
1 of 2
5
First off, i strongly recommend that you write C++ like C++ and not like C. If you are not from a C background, throw away the learning resource you are using and run (this is not an exaggeration). Instead use www.learncpp.com . Your problem is that newSet->arr = new int(member); constructs a single integer with value member and not an array. Hence any array access to it afterwards is UB. Further, in your insert function, you use Set::i, but it is not initialized. More UB. Finally, you fail to clean up setA in main. A better approach would be Use std::vector: int main() { std::vector setA; setA.push_back(5); setA.push_back(5); setA.push_back(5); setA.push_back(5); for ( const auto value : setA ) { std::cout << value << '\n'; } } or even better std::vector setA = { 5,5,5,5 }; Write it yourself, but actually write C++, i.e. use member functions, constructors and destructors: struct Set { int capacity = 0; int used_capacity = 0; int* arr = nullptr; Set( const int capacity ) //constructor : capacity( capacity ), arr( new int[capacity] ) //member initializer list {} ~Set() //destructor { delete[] arr; //cleans up the resource } void insert( int value ) { if ( used_capacity < capacity ) //check if there actually is space left { arr[ used_capacity++ ] = value; } } void print() { for ( int i=0; i < used_capacity; ++i ) { std::cout << arr[i] << '\n'; } } }; int main() { Set setA( 4 ); //dont use `new` if you dont have to. setA.insert( 5 ); setA.insert( 5 ); setA.insert( 5 ); setA.insert( 5 ); setA.print(); } //no need to call any `delete` because the destructor does it for you
2 of 2
1
new int(member); // thats a single int on heap with value 'member' new int[member]; // thats an int array on heap with size 'member' Thats btw C what youre writing, not C++
🌐
University of Texas
cs.utexas.edu › ~fussell › courses › cs310h › lectures › Lecture_18-310h.pdf pdf
C Dynamic Data Structures
Each array element is a struct (7 words, in this case). ... Because the [] and . operators are at the same precedence, and both associate left-to-right, this is the same as: ... Because the . operator has higher precedence than *, ... Most of the time, you’ll want to pass a pointer to a struct. ... Allocate storage for data dynamically, as needed.
Top answer
1 of 4
5

You have several errors in your source code:

  • struct *struct_array; (l. 5)
    What does it mean? Did you want to write struct data *struct_array?

  • printf("%s ", struct_array[i].inputA); (l.32 & l. 33)
    The argument struct_array masks the global declaration, and it is not an array. Why did you add this argument?

  • struct_array = (int *)realloc(n * sizeof(int)); (l. 39)
    You have forgotten an argument. Did you want to use malloc instead? Besides, the cast is not necessary (and incorrect!).

  • Unless you are using an hosted environnment and C99/C11, you should return a value from main.

  • Your variable index is not used. Why did you declare it?

  • for(i = n; i < n; i++) (l. 53) You won't have any iteration here...

The following code works as expected.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* TODO: Avoid global variables. */
struct data *struct_array;

struct data {
    char inputA[20];
    char inputB[20];
};

/* 
 * TODO: Try to avoid passing your structure (40 bytes + padding) 
 * without pointer. 
 */
struct data get_data(void)
{
    struct data thisdata;

    printf("Please enter input A\n");

    /* TODO: Avoid using `scanf` for human inputs. */
    scanf("%s", thisdata.inputA);

    printf("Please enter input B\n");
    scanf("%s", thisdata.inputB);

    return thisdata;
}

void Output(size_t n)
{
    size_t i;
    for (i = 0; i < n; i++) {
        printf("%s ", struct_array[i].inputA);
        printf("%s ", struct_array[i].inputB);
    }
}

void resizeArray(size_t n)
{
    /* TODO: Handle reallocations errors. */
    struct_array = realloc(struct_array, n * sizeof *struct_array);
}

void mainMenu(void)
{
    size_t i, n;
    int p;

    /* TODO: Use a loop ? */
    printf("Please select from the following options:\n");
    printf("1: Add new students to database\n");
    printf("2: Display current student database contents\n");
    printf("3: exit the program\n");
    scanf("%d", &p);

    switch (p) {
    case 1:
        printf("Please enter the number of students to register:\n");
        scanf("%u", &n);
        resizeArray(n);

        for (i = 0; i < n; i++)
            struct_array[i] = get_data();
        break;
    case 2:
        Output(n);
        break;
    }
}

int main(void)
{
    struct_array = malloc(2 * sizeof(int));
    mainMenu();
    free(struct_array);
    return 0;
}
2 of 4
5

Your definition

struct *struct_array;

is erroneous. You must use the name of your type, the data.

struct data *struct_array;

This way you can allocate the array

struct_array = malloc(MaxNumElements * sizeof(struct data));

and later you should free the memory

free(struct_array);

EDIT: Type definition must occur before the var declaration.

struct data ....

struct data* your_variable;

P.S. If you do not want to type struct keyword each time you use the data type, use the typedef:

typedef struct data_s
{
   char inputA[20];
   char inputB[20];    
} data;
Top answer
1 of 4
8

I am also concerned if there can be situation that I free a pointer twice in my case

... and ...

Yes just I am more interested in cases when/if there can be for example freeing unallocated memory or freeing already freed memory ...

After a quick inspection it doesn't appear that you free memory more than once:

  • free statements are only in the freeArray and main methods
  • Each free(a->array[0].name); is different because each name is allocated using its own malloc
  • free(a->array) is only called once
  • freeArray is only called once
  • free(x.name); doesn't free the same memory as free(a->array[0].name); because insertArray allocates new memory for each name

and how to avoid that

Something which can help (though not guarantee) is to assign NULL to the pointer after you pass it to free.

  • It can help, because calling free on a previously-nulled pointer will harmlessly do nothing
  • It's not a guarantee, because you might have more than one pointer pointing to the same memory

dmcr_code's comment below points out a bug. You wrote,

for(int i=0; i<a->used; i++)
{
    free(a->array[0].name);
    a->array[0].name=NULL;
}

This should be,

for(int i=0; i<a->used; i++)
{
    free(a->array[i].name);
    a->array[i].name=NULL;
}

Because you set a->array[0].name=NULL; after freeing it, you don't free it twice.

But, you did fail to free the memory associated with a->array[i].name for values of i larger than 0.


But then how do I protect against that - when array[i].name can contain random value and I try to free it?

To protect yourself:

  • Either, don't let it contain a random value (e.g. ensure that it's either a valid pointer, or zero)
  • Or, don't use it (e.g. ensure that your a->used logic is correct so that you don't touch elements which you haven't used/initialized).

is memset in the initArray method fine for that?

memset is good:

  • You could use calloc instead of malloc to avoid having to use memset as well
  • You could use memset on the whole array at once instead of using memset on each element of the array

memset in initArray isn't enough. It's enough to begin with, but there's a realloc in insertArray. So to be good enough, you'd also need to use memset after realloc (to memset the as-yet-unused end of the newly-reallocated array; without using memset on the beginning of the reallocated array, which already contains valid/initialized/used elements).

the only unclear part that remains from your response is how to memset realloced array

Your current code in initArray says,

// Initialize all values of the array to 0
for(unsigned int i = 0; i<initialSize; i++)
{
    memset(&a->array[i],0,sizeof(Student));
}

Another way to do that would be:

// Initialize all elements of the array at once: they are contiguous
memset(&a->array[0], 0, sizeof(Student) * initialSize);

The memset statement to add to insertArray would be:

if (a->used == a->size)
{
    a->size *= 2;
    a->array = (Student *)realloc(a->array, a->size * sizeof(Student));
    // Initialize the last/new elements of the reallocated array
    for(unsigned int i = a->used; i<a->size; i++)
    {
        memset(&a->array[i],0,sizeof(Student));
    }
}

Or:

if (a->used == a->size)
{
    a->size *= 2;
    a->array = (Student *)realloc(a->array, a->size * sizeof(Student));
    // Initialize the last/new elements of the reallocated array
    memset(&a->array[a->used],0,sizeof(Student) * (a->size - a->used));
}

and this comment: "It's not a guarantee, because you might have more than one pointer pointing to the same memory " would be nice if you can address that too

This is safe:

void* foo = malloc(10);
free(foo);
// protect against freeing twice
foo = NULL;
// this is useless and strange, but harmless
free(foo);

This is not safe:

void* foo = malloc(10);
void* bar = foo;
free(foo);
// protect against freeing twice
foo = NULL;
// this is useless and strange, but harmless
free(foo);
// but this is dangerous, illegal, undefined, etc.
// because bar is now pointing to memory that has already been freed
free(bar);
2 of 4
5

I have 3 suggestions.

  • If you need to allocate memory and initialize it to zero use calloc.
    Using calloc is better than using malloc + memset

    So change your initArray function like:

    void initArray(Array *a, size_t initialSize)
    {
       // Allocate initial space
       a->array = (Student *)calloc(initialSize , sizeof(Student));
    
       a->used = 0;           // no elements used
       a->size = initialSize; // available nr of elements
    }
    
  • Single character variable names are very bad. Use proper names for variables and follow naming conventions.

  • In your code you are only creating and adding 3 objects. But you are trying to print the details of 4th object. (Array index is starting from zero, so index 3 means 4th object)

    printf("%d\n", a.array[3].ID);   
    printf("%s\n", a.array[3].name);   
    
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-create-dynamic-array-inside-structure-in-c
How to Create a Dynamic Array Inside a Structure? - GeeksforGeeks
July 23, 2025 - Then initialize the dynamic array with that size using malloc() to dynamically allocate memory for the array. // Define the structure struct StructName { dataType* arrayName; int size; }; // In function StructName variableName; variableName.arrayName = new dataType[size]; variableName.size = size; ... StructName is the name of the structure. ... The below program demonstrates how we can create a dynamic array inside a structure in C++.
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › accelerated computing › cuda › cuda programming and performance
Dynamic array inside struct - CUDA Programming and Performance - NVIDIA Developer Forums
June 27, 2009 - Hi all! I’m trying to allocate a struct with a dynamic array to use as a SOA. typedef struct s { int *array; int size; } soa; So, I try to allocate memory as usual: soa *test; cudaMalloc((void**)&test, sizeof…
🌐
YouTube
youtube.com › portfolio courses
Dynamically Allocate An Array Of Structs | C Programming Tutorial - YouTube
How to dynamically allocate an array of structs in C, including how to use realloc() to re-allocate and increase the size of the array, and a warning about p...
Published   October 8, 2022
Views   34K
🌐
Bytesbeneath
bytesbeneath.com › p › dynamic-arrays-in-c
Dynamic Arrays in C - by Dylan Falconer - Bytes Beneath
January 18, 2024 - There is no doubt that the dynamic array is the most useful data structure. It's the go-to for most programmers until they may need something more specialised because they are fast and simple. Some algorithms require an unknown number of values to be stored, either temporarily during the running of algorithm, or as the result. In cases like this, the caller of the algorithm must either know the upper bound and allocate an array with enough space, or use a dynamic array that can grow in size as required.