Hello everyone, I am Xiaokang.
Today, let’s talk about a seemingly sophisticated yet super practical concept in C language—flexible arrays.
Don’t be intimidated by the name; what does “flexible” mean? Simply put, it refers to an array with variable size and undefined length. Mastering this technique can significantly enhance your programming skills!
⚡ Friendly Reminder: Follow me to stay updated! More hardcore technical articles will be shared later, guiding you through Linux C/C++ programming! 😆
1. What is a Flexible Array? Don’t Panic!
You must have used a regular array, right? For example: <span>int nums[10]</span>
. Once the size of this array is set to 10 elements, it cannot be more or less; it’s very rigid!
So, what is a flexible array? It is a magical feature introduced in the C99 standard that allows us to declare an array of unknown size at the end of a structure. Sounds mysterious? Don’t worry, you’ll understand after reading this!
2. What Does a Flexible Array Look Like?
struct FlexArray {
int length; // Record the length of the array
double scores[]; // This is the flexible array! Note that the size is not specified here
};
Did you see that? The brackets after the <span>scores</span>
array are empty! This is how you write a flexible array. It must be the last member of the structure, and there must be at least one other member before it (usually used to record the actual length of the array).
3. Why Use Flexible Arrays? What Are the Benefits?
Imagine this scenario: you need to manage the scores of different students, some of whom have taken 3 courses, while others have taken 8 courses. What do you do with a regular array?
Method 1: Define a sufficiently large array, for example:
struct Student {
int id;
int courseCount;
double scores[30]; // Fixed size of 30, just large enough
};
// Usage
struct Student xiaoming;
xiaoming.id = 1001;
xiaoming.courseCount = 5;
xiaoming.scores[0] = 85.5;
// ...
The problem is, this wastes space! Xiaoming only took 5 courses, but we allocated space for 30 courses. Moreover, what if a top student takes more than 30 courses? Changing the code and recompiling? That’s too troublesome!
Method 2: Use pointers and dynamic memory, for example:
struct Student {
int id;
int courseCount;
double *scores; // Pointer, pointing to another memory block
};
// Usage
struct Student *xiaoming = (struct Student*)malloc(sizeof(struct Student));
xiaoming->id = 1001;
xiaoming->courseCount = 5;
// Allocate memory for the scores array
xiaoming->scores = (double*)malloc(5 * sizeof(double));
xiaoming->scores[0] = 85.5;
// ...
// Remember to free memory twice!
free(xiaoming->scores); // First free the array
free(xiaoming); // Then free the structure
This method is flexible, but it requires two memory allocations each time: one for the structure and one for the array pointed to by scores. The memory is not contiguous, access efficiency is low, and it’s easy to forget to free memory (especially the memory pointed to by the scores pointer; many people only free the structure and forget to free the array, causing memory leaks).
At this point, flexible arrays become particularly clever!
4. How to Use Flexible Arrays? Let’s Get Practical!
#include <stdio.h>
#include <stdlib.h>
// Define a structure with a flexible array
struct Student {
int id; // Student ID
int courseCount; // Number of courses
double scores[]; // Flexible array to store scores
};
int main() {
int courses = 5; // Xiaoming took 5 courses
// Calculate the total memory needed: fixed part of the structure + flexible array part
struct Student *xiaoming = (struct Student*)malloc(sizeof(struct Student) + courses * sizeof(double));
// Initialize Xiaoming's information
xiaoming->id = 1001;
xiaoming->courseCount = courses;
// Set Xiaoming's scores for 5 courses
xiaoming->scores[0] = 85.5; // Math
xiaoming->scores[1] = 92.0; // English
xiaoming->scores[2] = 78.5; // Physics
xiaoming->scores[3] = 96.0; // Chemistry
xiaoming->scores[4] = 88.5; // Biology
// Calculate the average score
double sum = 0;
for (int i = 0; i < xiaoming->courseCount; i++) {
sum += xiaoming->scores[i];
}
printf("Xiaoming's average score is: %.2f\n", sum / xiaoming->courseCount);
// Free memory, only need to free once!
free(xiaoming);
return 0;
}
Output:
Xiaoming's average score is: 88.10
5. Memory Layout of Flexible Arrays: Understand It at a Glance!
Assuming we have the following structure:
struct FlexArray {
int length;
double scores[];
};
The memory layout looks something like this:
+-------------+-------------+-------------+-------------+
| length (4B) | scores[0] | scores[1] | scores[2] | ...
+-------------+-------------+-------------+-------------+
↑
Starting position of the flexible array
All data is in a contiguous block of memory, access is super fast, and you only need to allocate and free memory once!
6. Cautions for Flexible Arrays (Pitfall Warning ⚠️)
- Must be at the end of the structure: The flexible array must be the last member of the structure.
- At least one other member: The structure must have at least one other member (usually used to record the length of the flexible array).
- Does not count towards structure size: The flexible array is not included in the sizeof size of the structure.
struct Test {
int n;
int arr[];
};
printf("Structure size: %zu\n", sizeof(struct Test)); // Output: Structure size: 4
- Cannot directly define variables: You cannot directly define structure variables; you must use pointers and dynamic memory.
// Incorrect way
struct Test t; // Not allowed! No space for flexible array
// Note: Although it may compile in modern compilers like VS2022
// This is not standard; the flexible array has no actual storage space, using it will lead to memory overflow!
// Correct way
struct Test *pt = (struct Test*)malloc(sizeof(struct Test) + 10 * sizeof(int));
7. Flexible Arrays vs Pointer Members: What’s the Difference?
Some may ask: Can’t we achieve similar functionality with pointer members in structures?
struct WithPointer {
int length;
int *data; // Pointer member
};
struct WithFlexible {
int length;
int data[]; // Flexible array
};
The differences are significant:
- Memory Layout: The data of a flexible array is contiguous right after the structure; with pointers, the data is in another location, resulting in two non-contiguous memory blocks.
- Memory Operations: Flexible arrays require only one allocation and deallocation; pointer methods require two.
- Access Efficiency: Flexible arrays are faster to access, with contiguous memory that is more CPU cache-friendly.
- Code Simplicity: Flexible arrays lead to cleaner code and reduce the chances of forgetting to free memory.
8. Practical Case: Implementing a Simple Dynamic String
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
size_t length; // String length
char data[]; // Flexible array
} MyString;
// Create a string
MyString* createString(const char* text) {
size_t len = strlen(text);
// Allocate memory: structure size + string length + 1 (for '\0')
MyString* str = (MyString*)malloc(sizeof(MyString) + len + 1);
str->length = len;
strcpy(str->data, text); // Copy string content
return str;
}
// Print string
void printString(const MyString* str) {
printf("Length: %zu, Content: %s\n", str->length, str->data);
}
int main() {
// Create a string
MyString* hello = createString("Hello, Flexible Arrays!");
// Print string information
printString(hello);
// Free memory, only need to free once
free(hello);
return 0;
}
Output:
Length: 16, Content: Hello, Flexible Arrays!
Conclusion: What Makes Flexible Arrays So Attractive?
- Contiguous Memory: Data is compact, leading to high access efficiency
- Single Allocation: Avoid multiple malloc/free, reducing memory fragmentation
- Single Deallocation: Less likely to cause memory leaks
- Flexible and Convenient: Allows for just the right amount of memory allocation as needed
Doesn’t C language suddenly feel more powerful? This small trick of flexible arrays is widely used in many low-level libraries and system programming, such as in the Linux kernel.
Alright, that’s it for today’s C language class! Next time, we’ll discuss other interesting programming techniques. If you found this helpful, don’t forget to like and follow!
Mastering this small trick of flexible arrays makes you feel like your C language skills have leveled up, right?
Final Note: Technical Growth Has No “Fixed Size”
Just like flexible arrays, our learning journey should not be limited to a rigid size. From basic C language to advanced techniques, from programming novices to technical experts, each stage requires a different “length” of knowledge.
If you want your technical abilities to expand flexibly like flexible arrays, feel free to follow my public account “Learn Programming with Xiaokang“. There, I will continue to explain in simple terms:
- The complex underlying principles of computers that are often complicated in textbooks
- The core techniques of Linux C/C++ that are frequently asked by interviewers
- The practical programming experiences regarded as “black magic” by colleagues
- And programming knowledge like flexible arrays that seems profound but is actually super practical
Give a “like” and “look” to avoid letting your technical growth “leak memory”! Or share with friends who need it~ Your support is the driving force for my continued sharing~
Have you ever used flexible arrays in your projects? Feel free to share your experiences in the comments!
How to follow my public account?
Click on the public account card below to follow.
Additionally, Xiaokang has created a technical exchange group, specifically for discussing technology and answering questions. If you encounter any unclear points while reading the article, feel free to ask in the group! I will do my best to help everyone, and there are many technical experts online to support us, so let’s learn and grow together!

Previous Good Articles:Unveiling the Core Technology of Operating Systems: How Processes and Threads Were Invented Step by Step?Can’t C Language Define Variable Length Arrays? Don’t Joke Around!malloc(0): Not a Byte Needed, Yet Still Able to Get Memory?Shh! A Little Secret About Volatile, Only 1% Know It, But It Can Help You Avoid 99% of Pitfalls!C Language Structure Memory Alignment: So That’s How It Is!Deep Analysis of C Language Memory Layout: From Stack to Heap, Do You Really Understand?