
- C - Home
- C - Overview
- C - Features
- C - History
- C - Standards
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Basic Syntax
- C - User Input
- C - printf Function
- C - Format Specifiers
- Lexical Elements in C
- C - Tokens
- C - Keywords
- C - Identifiers
- Variables and Constants
- C - Variables
- C - Constants
- C - Const Qualifier
- C - Linkage
- Data Types and Type Conversions
- C - Data Types
- C - Literals
- C - Escape sequences
- C - Booleans
- C - Integer Promotions
- C - Character Arithmetic
- C - Type Conversion
- C - Type Casting
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Unary Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Miscellaneous Operators
- Decision Making & Control Statements
- C - Decision Making
- C - if statement
- C - if...else statement
- C - if...else if Ladder
- C - Nested if statements
- C - Switch statement
- C - Nested switch statements
- C - Switch Case Using Range
- Loops in C
- C - Loops
- C - For Loop
- C - While Loop
- C - Do...while Loop
- C - For Loop vs While Loop
- C - Nested Loop
- C - Infinite Loop
- C - Break Statement
- C - Continue Statement
- C - Goto Statement
- Functions in C
- C - Functions
- C - Function Prototype
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- C - Predefined Identifier __func__
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- C - Dynamic Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Character Arrays
- C - Special Characters
- Structures and Unions in C
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Dot (.) Operator
- C - Lookup Tables
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Function Pointers
- C - Array of Function Pointers
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Pointer to an Array
- C - Pointers vs. Multi-dimensional Arrays
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Const Pointers & Pointer to Const
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Restrict Keyword
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Initialization of Pointer Arrays
- C - Flexible Array Members in Structures
- C - Structures vs Unions
- Storage Classes and Qualifiers
- C - Storage Classes
- Memory Management in C
- C - Memory Layout
- C - Memory Management
- C - Memory Address
- C - Memory Leaks
- Preprocessors in C
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- File Handling in C
- C - File I/O (File Handling)
- C - Input & Output
- Constants and Literals in C
- C - Macros
- C - Header Files
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
- C Online Compiler
C - Flexible Array Members in Structures
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 −
struct StructName { data_type member1; data_type member2; // ... };
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 −
struct StructName { data_type member1; data_type flexible_array[]; // flexible array member };
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> struct Example { int id; int arr[]; // flexible array member }; int main() { int size = 5; // Allocate memory for structure + flexible array struct Example *e = malloc(sizeof(struct Example) + size * sizeof(int)); if (e != NULL) { printf("Total allocated memory: %zu bytes\n", sizeof(struct Example) + size * sizeof(int)); free(e); } return 0; }
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> struct Student { int id; int marks[]; // flexible array member }; int main() { int subjects = 3; // Allocate memory for structure + flexible array struct Student *s = malloc(sizeof(struct Student) + 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(struct Student) + subjects * sizeof(int)); free(s); } return 0; }
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> struct Student { int id; int count; // This field helps track current array size int marks[]; // Flexible array member }; int main() { // Step 1: Initial allocation for 3 marks int initial_elements = 3; struct Student *s = malloc(sizeof(struct Student) + initial_elements * sizeof(int)); if (s != NULL) { s->id = 101; s->count = initial_elements; // Store current array size // Display initial sizes printf("Structure size: %zu bytes\n", sizeof(struct Student)); // Output: 8 bytes (id + count) printf("Initial array elements: %d\n", s->count); // Output: 3 printf("Initial total memory: %zu bytes\n", sizeof(struct Student) + initial_elements * sizeof(int)); // Output: 20 bytes // Step 2: Resize to hold 6 marks int new_elements = 6; struct Student *temp = realloc(s, sizeof(struct Student) + new_elements * sizeof(int)); if (temp != NULL) { s = temp; s->count = new_elements; // Update array size tracker // Display new sizes printf("\nAfter resizing:\n"); printf("Structure size: %zu bytes\n", sizeof(struct Student)); // Still 8 bytes printf("New array elements: %d\n", s->count); // Output: 6 printf("New total memory: %zu bytes\n", sizeof(struct Student) + new_elements * sizeof(int)); // Output: 32 bytes } free(s); } return 0; }
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.