Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:

struct line* array = malloc(number_of_elements * sizeof(struct line));

In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().

Note that's it's better style to use:

sizeof(*array)

instead of:

sizeof(struct line)

The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.

Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:

typedef struct line
{
    char* addr;
    char* inst;
} line;

You can then just do:

line* array = malloc(number_of_elements * sizeof(*array));

Of course don't forget to also allocate memory for array.addr and array.inst.

Answer from Nikos C. on Stack Overflow
Top answer
1 of 2
37

Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:

struct line* array = malloc(number_of_elements * sizeof(struct line));

In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().

Note that's it's better style to use:

sizeof(*array)

instead of:

sizeof(struct line)

The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.

Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:

typedef struct line
{
    char* addr;
    char* inst;
} line;

You can then just do:

line* array = malloc(number_of_elements * sizeof(*array));

Of course don't forget to also allocate memory for array.addr and array.inst.

2 of 2
10

For what you have described, You do not need to allocate memory for your struct, rather, you need to allocate memory for the members char *addr;, and char *inst;. If you want to have a single copy of that structure, the first section of code illustrates how to initialize, and assign values. If you want an array, the second code example illustrates the differences.

This illustrates how to allocate memory for the members of a single struct line:

typedef struct
{
    char* addr;
    char* inst;
}LINE;

LINE line;  

int main(void)
{   

    strcpy(line.addr, "anystring"); //will fail
    line.addr = malloc(80);
    line.inst = malloc(80);
    strcpy(line.addr, "someString");//success;
    strcpy(line.inst, "someOtherString");//success;

}

For array of struct line...

typedef struct
{
    char* addr;
    char* inst;
}LINE;  //same struct definition

LINE line[10]; //but create an array of line here.

int main(void)
{   
    int i;
    
    for(i=0;i<10;i++)
    {
      line[i].addr = malloc(80);
      line[i].inst = malloc(80);
    }

    for(i=0;i<10;i++)
    {
        strcpy(line[i].addr, "someString");
        strcpy(line[i].inst, "someOtherString");
    }
    //when done, free memory
    for(i=0;i<10;i++)
    {
        free(line[i].addr);
        free(line[i].inst);
    }      


}

Added to address comment
Addressing the comment under this answer from @Adam Liss, the following code illustrates the following improvements using strdup(): 1) Uses only memory needed. 2) Performs memory creation and copy operations in one step, so the the following blocks:

for(i=0;i<10;i++)
{
  line[i].addr = malloc(80);
  line[i].inst = malloc(80);
}

for(i=0;i<10;i++)
{
    strcpy(line[i].addr, "someString");
    strcpy(line[i].inst, "someOtherString");
}

Become:

for(i=0;i<10;i++)
{
  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");
}

One more note: Error handling was not included in examples above to avoid muddling up focus on the main concepts: But for the sake of completeness, because both malloc() and strdup() can fail, actual usage for each of these two functions, should include a test before using, eg:

Rather than

  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");

The code should include

  line[i].addr = strdup("someString");
  if(!line[i].addr)
  {
      //error handling code here
  }
  line[i].inst = strdup("someOtherString");
  if(!line[i].inst)
  {
      //error handling code here
  }
🌐
Quora
quora.com › How-do-I-malloc-an-array-of-structs-in-C
How to malloc() an array of structs in C - Quora
Answer (1 of 3): Let’s say you have defined a struct X, and you want to allocate an array of N of these structs. Then, [code]struct X *pArray = malloc(sizeof(struct X) * N); if (pArray) { // Access elements using pArray } [/code]It’s really that simple. You can use pArray with square bracket ...
Discussions

How to malloc for an array of structs in c - Stack Overflow
I have searched for a way to do this on my own, but I haven't found a situation that exactly matches mine and I'm not experienced enough to derive what to do from similar situations. So I'm hoping... More on stackoverflow.com
🌐 stackoverflow.com
August 13, 2014
c - malloc an array of struct pointers - Stack Overflow
I get an error: incompatible types when assigning to type ‘struct _chess’ from type ‘void *’ · Any idea what am I doing wrong? Thanks. ... WHy typedef the struct? it has a unique type already. ... Stop using pointer typedefs, you are just confusing yourself. chess *array = malloc(size ... More on stackoverflow.com
🌐 stackoverflow.com
September 9, 2015
How to malloc arrays inside structs?
int* arr1, arr2; This declares arr1 to be int* but arr2 to only be an int. You need int *arr1, *arr2; The Bjarnish declaration with pointers gets confusing if you put multiple variables in the same declaration. I'd just do int* arr1; int* arr2; More on reddit.com
🌐 r/C_Programming
13
4
June 15, 2022
c - How to free() an array of structs allocated by malloc()? - Stack Overflow
You do not need to free each of the 30 structures of type struct datastore1 in memory individually. ... Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined. ... As far as I understand you only used malloc to allocate space for an array ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Delft Stack
delftstack.com › home › howto › c array of structs
How to Create Array of Structs in C | Delft Stack
February 12, 2024 - Its syntax is as follows: ... Here, ... the case of creating an array of structs, we determine the size by multiplying the number of elements by the size of each struct using sizeof....
🌐
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 - The malloc function returns the pointer of void type to the memory allocated of the given size. We then use typecasting to cast this pointer to the desired type which here is the pointer to struct.
Top answer
1 of 4
49

array is a slightly misleading name. For a dynamically allocated array of pointers, malloc will return a pointer to a block of memory. You need to use Chess* and not Chess[] to hold the pointer to your array.

Chess *array = malloc(size * sizeof(Chess));
array[i] = NULL;

and perhaps later:

/* create new struct chess */
array[i] = malloc(sizeof(struct chess));

/* set up its members */
array[i]->size = 0;
/* etc. */
2 of 4
23

There's a lot of typedef going on here. Personally I'm against "hiding the asterisk", i.e. typedef:ing pointer types into something that doesn't look like a pointer. In C, pointers are quite important and really affect the code, there's a lot of difference between foo and foo *.

Many of the answers are also confused about this, I think.

Your allocation of an array of Chess values, which are pointers to values of type chess (again, a very confusing nomenclature that I really can't recommend) should be like this:

Chess *array = malloc(n * sizeof *array);

Then, you need to initialize the actual instances, by looping:

for(i = 0; i < n; ++i)
  array[i] = NULL;

This assumes you don't want to allocate any memory for the instances, you just want an array of pointers with all pointers initially pointing at nothing.

If you wanted to allocate space, the simplest form would be:

for(i = 0; i < n; ++i)
  array[i] = malloc(sizeof *array[i]);

See how the sizeof usage is 100% consistent, and never starts to mention explicit types. Use the type information inherent in your variables, and let the compiler worry about which type is which. Don't repeat yourself.

Of course, the above does a needlessly large amount of calls to malloc(); depending on usage patterns it might be possible to do all of the above with just one call to malloc(), after computing the total size needed. Then you'd still need to go through and initialize the array[i] pointers to point into the large block, of course.

🌐
Linux Hint
linuxhint.com › array-of-structs-malloc
How to Use Malloc Function to Create Array of Structs – Linux Hint
If you don’t want to put a limit on the number of characters for the employee name then you can simply take the input first for the employee name inside the for loop within a new variable and then pass that variable size in the malloc function. The struct data type in C programming provides better performance when we have to deal with small groups of the same values. In this write-up, we have discussed the creation of structs with arrays using the dynamic memory function that is malloc() function.
Find elsewhere
🌐
Reddit
reddit.com › r/c_programming › how to malloc arrays inside structs?
r/C_Programming on Reddit: How to malloc arrays inside structs?
June 15, 2022 -

I would like to have a struct containing several dynamically allocated arrays. I've tried several variations of the following code:

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

struct rectangle 
{
    int 
    width,
    height;
    int* 
    arr1,
    arr2;
};

int main()
{       
    int n = 3;
    struct rectangle box1 = 
    {
       .width = 3,
       .height = 4,
       .arr1 = (int*) malloc( n * sizeof(int)),
       .arr2 = (int*) malloc( n * sizeof(int))
    }; 
}

However, I keep getting warning: initialization from int to int* makes integer from pointer without a cast [-Wint-conversion].

🌐
Delft Stack
delftstack.com › home › howto › c malloc struct
How to Allocate Struct Memory With malloc in C | Delft Stack
February 12, 2024 - In this method, memory is allocated to store an array of structures using malloc. The following example code demonstrates the case when the array of 100 pointers to the MyObject structs is declared on the stack, but each individual MyObject object is allocated on dynamic memory (heap).
Top answer
1 of 4
7

How should i free the allocated memory that was used after calling malloc?

Consider below example,

struct datastore1 *obj1 = malloc(sizeof(struct datastore1));
free(obj1);

Here obj1 is pointing to the block of memory of size same as size of datastore1 in order to free you need to send the address which is allocated by malloc.

likewise,

struct datastore1 *obj2 = malloc(3 * sizeof(struct datastore1));
free(obj2);

obj2 is pointing to a block of contiguous memory of size 3 * sizeof(datastore1) you need to pass the base address to free

Should i free each indexes individually?

NO, Since block of memory is allocated only once and you need to free exactly one time.

Let me extend it further,

struct datastore1 *obj3[3];
for(int i=0;i<3;i++)
   obj3[i] = malloc(sizeof(struct datastore1));

for(int i=0;i<3;i++)
    free(obj3[i]);

Here obj3 is array of pointer and each index is pointing to different part of memory and hence need to be freed individually.


Note: For simplicity I haven't considered return value from malloc. Null check has to be done on malloc return value.

2 of 4
1

1.

How should I free the allocated memory that was used after calling malloc?

I tried doing free(dsdata) on the end of the program but I am not sure if it's the right way.

free(dsdata) is fine, since you allocated the whole space by just one call to malloc with:

struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));

To cite the standard (C18), 7.22.3.4 - "The malloc function" (emphasize mine):

7.22.3.4 The malloc function

Synopsis

1

 #include <stdlib.h>
 void* malloc(size_t size);

Description

2 The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.

Returns

3 The malloc function returns either a null pointer or a pointer to the allocated space.

It is correct to use free(dsdata) because malloc allocated all of the required space at once and returned a pointer to the first structure variable of this array which is assigned to the pointer of dsdata.

The free() function "knows" that dsdata is a reference to the whole allocated space. You do not need to free each of the 30 structures of type struct datastore1 in memory individually.


2.

Should I free each indexes individually?

No, you do not need and even more important you should not do so; this would be Undefined Behavior:

Citation from the current standard (C18), 7.22.3.5/3 - "The free function" (emphasize mine):

Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

🌐
W3Schools
w3schools.com › c › c_memory_struct.php
C Structures and Dynamic Memory
If you need more elements later, you can resize your dynamic array with realloc(). This may move the block to a new location and returns a new pointer. Always store the result in a temporary pointer first to avoid losing the original memory if reallocation fails. #include <stdio.h> #include <stdlib.h> #include <string.h> struct Car { char brand[50]; int year; }; int main() { int count = 2; struct Car *cars = (struct Car*) malloc(count * sizeof(struct Car)); if (cars == NULL) { printf("Initial allocation failed.\n"); return 1; } // Initialize first 2 cars strcpy(cars[0].brand, "Toyota"); cars[0
Top answer
1 of 3
3

Your problem is the way you declared the struct it should be

struct data 
{
    int *ref; 
    int *port;
    char data[MAX_STRING];
};

and then you do

struct data *p_valid;
p_valid = malloc(sizeof(struct data));

another thing is

p_valid->data = malloc(sizeof(STRINGMAX));

is wrong because data is not a pointer. And sizeof(STRINGMAX) is wrong too, since STRINGMAX seems to be a macro and hence it will expand to it's value say if you have #define STRINGMAX 4 then it would expand to sizeof(4).

2 of 3
1
Your definition of the struct:

struct data {
    int *ref; 
    int *port;
    char data[MAX_STRING];
}temp, valid, invalid;

should be more like this:

struct data 
{
    int *ref; 
    int *port;
    char data[MAX_STRING];
};

then define the arrays similar to this:

struct data temp;

struct data* valid = NULL;
struct data* invalid = NULL;
int currentValidSize = 0;
int currentInvalidSize = 0;
struct data * validTemp = NULL;
struct data * invalidTemp = NULL;

then, each time the code needs room for (another) instance of a struct

struct data *validTemp = realloc(valid, (currentValidSize+1)* sizeof(data) );
if( NULL == validTemp )
{ // realloc failed
    perrof( "realloc failed" );

    // free everything, close files, etc here probably be writing a sub function
    // and calling it here.
    // a sub function that: 
    // that walks the valid and invalid arrays, 
    // first free'ing any malloc'd fields
    // then finally free'ing the whole array

    exit( EXIT_FAILURE );
}

// implied else, realloc successful

// update array size counter
currentValidSize++;

// update ptr to valid array of structs
valid = validTemp;
validTemp = NULL;

similar for adding an entry to the invalid array of structs

then update the valid array of structs from temp as:
(note the '-1' in the offset into valid[])

memcpy( &valid[currentValidSize-1], &temp, sizeof data );
// Note you will also have to perform a 'deep' copy of any areas 
// that were malloc'd within the 'temp' struct
🌐
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. [code]#include #include #include typedef struct { ...
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);   
    
🌐
Stack Overflow
stackoverflow.com › questions › 45147695 › malloc-array-of-struct-in-c
Malloc array of struct in C - Stack Overflow
July 17, 2017 - Check that the variable is not null before using it as an array (for example, assert(all_data != 0); at judicious points in the code). ... There is no code. Only some declarations. We are not a coding service. too honest for this site – too honest for this site · 2017-07-17 15:13:49 +00:00 Commented Jul 17, 2017 at 15:13 · Thank you, it was what I was looking for. However, why do you need to use a pointer to all_data, and not just struct get_data all_data = malloc(sizeof(all_data) * number_of_file);
🌐
HatchJS
hatchjs.com › home › how to allocate an array of structures with malloc in c
How to Allocate an Array of Structures with Malloc in C
January 5, 2024 - For example, the following code prints the name of the first person in the array: c printf(“The name of the first person is %s\n”, people[0].name); ... Always check the return value of malloc. malloc can fail if there is not enough memory available on the heap. If malloc fails, it will return a NULL pointer. You should always check the return value of malloc and take appropriate action if it fails. Use a size that is a multiple of the alignment requirement. The alignment requirement of a struct is the minimum number of bytes that must be allocated for each element of the struct.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 131225-malloc-array-structures.html
malloc() with array of structures
October 25, 2010 - "Finding the smallest program that demonstrates the error" is a powerful debugging tool. Look up a C++ Reference and learn How To Ask Questions The Smart Way ... typedef struct { int roll; }REC; int main() { int i, n =3; REC *pt= malloc(n*sizeof(*pt)); printf("\n* * * * Enter roll no of students.
Top answer
1 of 2
1

If you want an array of Element* then you could do something like this where is n is the number of pointers:

Element** arrayOfStructs = malloc( n* sizeof(Element*) ); 

So for n = 4; you get an array of 4 pointers:

arrayOfStructs

+---+
|   | ->
+---+
|   | ->
+---+
|   | ->
+---+
|   | ->
+---+

Now allocate for each entry in the arrayOfStructs so if m is the number of Elements:

for (int i = 0; i < n; ++i)
{
  arrayOfStructs[i] = malloc(m * sizeof(Element));
}

Since each element has a data pointer, you need to allocate what that points to as well:

for (int i = 0; i < n; ++i)
{
  arrayOfStructs[i] = malloc(m * sizeof(Element));
  for (int j = 0; j < m; ++j)
  {
    arrayOfStructs[i][j].data = malloc(sizeof(int));
  }
}

After this you will have the following in memory:

Let's say m = 3;

arrayOfStructs

+---+    +---+---+----+
|   | -> |   |   |    |  array of Elements
+---+    +---+---+----+    +---+---+----+
|   | -------------------> |   |   |    |
+---+    +---+---+----+    +---+---+----+
|   | -> |   |   |    |
+---+    +---+---+----+    +---+---+----+
|   | -------------------> |   |   |    |
+---+                      +---+---+----+

each element in "array of Elements" 1..3(or rather 0..2) point to a different "data" (below on array of Elements is turned around 90 degrees so I can more easily draw boxes):

+---+    +---+
|   | -> |   | integer
+---+    +---+   +---+
|   | ---------> |   |
+---+            +---+     +---+
|   | -------------------> |   |
+---+                      +---+
2 of 2
1

arrayOfElements is the name of a pointer variable. You cannot have an array of names.

You could have an array of pointer variables. You can write the code for that, it is the same as the code for an array of int, but use a pointer type instead of int. Then, you would need to initialize each of those pointer variables in the array the same way as you are doing now.

However, as posted, the question asked for "array of arrays", not "array of pointers". An "array of arrays" is an array where the element type is an array (not a pointer).

Here is a non-dynamically-allocated array: int x[4][5]; . This is an array of 4 elements, with each element being an array of 5 ints.

To dynamically allocate one of these, it is the same code as dynamically allocating any array of 4 elements. We just use int[5] as the element type, instead of int or whatever.

The type of the pointer to the first element is: "pointer to int[5]". In C syntax this is written int (*)[5] -- not int *[5] which is an array of pointers.

One way to write the code would be:

int (*px)[5] = malloc(4 * sizeof(int[5]));

hopefully you can see the similarity between this and the malloc in your question. We just replaced Element with int[5]. (So, your job now, is to use Element[5] instead of int[5]. Or whatever size instead of 5).

To avoid repetition (and so avoid the possibility of errors) it's possible to use the common idiom:

int (*px)[5] = malloc(4 * sizeof *px);

which is 4 elements each of the right size for what the pointer is pointing to.