Flexible Array Members is used to handle arrays inside structures without defining their size. These arrays get their size at runtime. A structure in C is a user-defined data type where we define multiple members of different data types together under one name.
Below is the syntax for declaring a structure in C −
structStructName{
data_type member1;
data_type member2;// ...};</code></pre>
Here, each member can have a different data type.
Flexible array members extend structures by holding a dynamically sized array at the end of their fixed-size members and all together stored in one block of memory. In this chapter, we'll see how they work inside the structures.
Flexible Array Members in Structure
A flexible array member is an array inside a structure without a fixed size, and its memory is allocated dynamically at runtime using malloc(), calloc(), or similar functions and it is declared using empty square brackets [].
The flexible array member must be declared at the end of the structure, and there must be at least one other member before declaring it.
Following is the syntax for declaring a flexible array member inside a structure −
structStructName{
data_type member1;
data_type flexible_array[];// flexible array member};</code></pre>
Here, data_type is the data type of the array, and arrayName[] is the flexible array with no fixed size.
Memory Allocation for Flexible Array Member
A flexible array member does not have a fixed size, so the compiler does not allocate any memory for it inside the structure. The sizeof operator only calculates the size of the fixed members of the structure without including the flexible array member. That's why we need to allocate memory manually when creating such structures.
The total memory required is calculated as −
Total Memory =sizeof(structure)+(number of elements x sizeof(element type))
Here, sizeof(structure) gives the memory for the fixed members, and (number of elements x sizeof(element type)) gives the memory for the flexible array. Adding them gives the total memory to allocate.
Example 1: Allocating Memory for a Flexible Array Member
Below is an example where we define a structure with one fixed member and a flexible array, and allocate memory for the flexible array.
#include <stdio.h>#include <stdlib.h>structExample{int id;int arr[];// flexible array member };intmain(){int size =5;// Allocate memory for structure + flexible arraystructExample*e =malloc(sizeof(structExample)+ size *sizeof(int));if(e !=NULL){printf("Total allocated memory: %zu bytes\n",sizeof(structExample)+ size *sizeof(int));free(e);}return0;}
Here, sizeof(struct Example) gives 4 bytes for the id member. Then, we calculate the memory for the flexible array: 5 x sizeof(int) = 20 bytes. The total memory allocated is 4 + 20 = 24 bytes. The output is −
Total allocated memory: 24 bytes
Example 2: Accessing a Flexible Array in a Structure
In this example, we define a Student structure with one fixed member (id) and a flexible array member (marks). We allocate memory dynamically for the flexible array and access its elements. If we access elements beyond the allocated size it will cause undefined behavior, so we only access marks[0] to marks[2].
#include <stdio.h>#include <stdlib.h>structStudent{int id;int marks[];// flexible array member};intmain(){int subjects =3;// Allocate memory for structure + flexible arraystructStudent*s =malloc(sizeof(structStudent)+ subjects *sizeof(int));if(s !=NULL){
s->id =102;
s->marks[0]=80;
s->marks[1]=75;
s->marks[2]=88;printf("Student ID: %d\n", s->id);printf("Marks: %d, %d, %d\n", s->marks[0], s->marks[1], s->marks[2]);printf("Total allocated memory: %zu bytes\n",sizeof(structStudent)+ subjects *sizeof(int));free(s);}return0;}</code></pre>
Following is the output of the above program −
Student ID: 102
Marks: 80, 75, 88
Total allocated memory: 16 bytes
Dynamic Resizing of Flexible Array Members
Flexible arrays can be resized using the realloc() function. This function either expands the existing memory block or allocates a new block and copies the existing data automatically.
To resize a flexible array, we call realloc() function with the new total memory size using the formula −
sizeof(structure)+(new_number_of_elements x sizeof(element_type))
Note: Always store the result of realloc() function in a temporary pointer. If it fails, your original pointer remains safe. Also, update the size counter after resizing and initialize only the newly added elements.
Example 3: Dynamic Resizing of Flexible Array Members
In this example, we create a Student structure to hold 3 marks initially. Later, we resize the flexible array to hold 6 marks using realloc(). The marks we already stored in remain unchanged, so we don't need to copy them manually.
#include <stdio.h>#include <stdlib.h>structStudent{int id;int count;// This field helps track current array sizeint marks[];// Flexible array member};intmain(){// Step 1: Initial allocation for 3 marksint initial_elements =3;structStudent*s =malloc(sizeof(structStudent)+ initial_elements *sizeof(int));if(s !=NULL){
s->id =101;
s->count = initial_elements;// Store current array size// Display initial sizesprintf("Structure size: %zu bytes\n",sizeof(structStudent));// Output: 8 bytes (id + count)printf("Initial array elements: %d\n", s->count);// Output: 3printf("Initial total memory: %zu bytes\n",sizeof(structStudent)+ initial_elements *sizeof(int));// Output: 20 bytes// Step 2: Resize to hold 6 marksint new_elements =6;structStudent*temp =realloc(s,sizeof(structStudent)+ new_elements *sizeof(int));if(temp !=NULL){
s = temp;
s->count = new_elements;// Update array size tracker// Display new sizesprintf("\nAfter resizing:\n");printf("Structure size: %zu bytes\n",sizeof(structStudent));// Still 8 bytesprintf("New array elements: %d\n", s->count);// Output: 6printf("New total memory: %zu bytes\n",sizeof(structStudent)+ new_elements *sizeof(int));// Output: 32 bytes}free(s);}return0;}</code></pre>
Below is the output showing the structure size and the total memory for both the initial and resized flexible array.
Structure size: 8 bytes
Initial array elements: 3
Initial total memory: 20 bytes
After resizing:
Structure size: 8 bytes
New array elements: 6
New total memory: 32 bytes
In this chapter, we learned about flexible array members in C structures. They are declared at the end of a structure and handle variable-length data, save memory, and adapt to different data sizes easily. We also saw how to allocate, access, and resize them.
Leave a Reply