1. What is a flexible array
The definition of an ordinary array must add a "constant" in square brackets after the array name. However, in actual use, the size of the array is often not known in advance. If it is too large, it is easy to waste space, and if it is too small, it is not enough. At this time, we need to introduce the concept of flexible array.
Flexible array is not a simple array variable, but a special custom structure type. The last element in the structure is allowed to be an array of unknown size. As defined below
typedef struct st_type { int i; //At least one other member must be defined before a flexible array int a []; //Flexible array //int a[0]; // You can also define a flexible array in this way }type_a;
2. Characteristics of flexible array
- A flexible array member in a structure must be preceded by at least one other member.
- The size of this structure returned by sizeof does not include the memory of the flexible array (even if it makes room for the flexible array).
- The structure containing flexible array members uses the * * malloc() * * function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to adapt to the expected size of the flexible array
It seems very obscure, because this is the refined conclusion. It is recommended to look at the following use cases first, and then come back to these three summaries.
3. Use of flexible arrays
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> /* Features of flexible array: 1.A flexible array member in a structure must be preceded by at least one other member. 2.sizeof This structure size returned does not include the memory of the flexible array. 3.The structure containing flexible array members uses malloc() function to dynamically allocate memory, and the allocated memory should be greater than the size of the structure Small to fit the expected size of the flexible array */ //Definition of flexible array typedef struct st_type { int i; //At least one other member must be defined before a flexible array int a []; //Flexible array //int a[0]; // You can also define a flexible array in this way }type_a; int main() { printf("%d\n", sizeof(type_a)); //The structure containing flexible array members uses malloc() function to dynamically allocate memory //Note: This is to open up space for the whole structure variable, not for the a pointer in the structure alone type_a* ps = (type_a*) malloc(sizeof(type_a) +10 * sizeof(int)); //When opening up space, you should also add the size of other members in front of the flexible number if (ps == NULL) { printf("%s\n", strerror(errno)); return -1; } ///Use of flexible arrays ps->i = 0; //You can assign values to the elements before the flexible array int i = 0; for (i = 0; i < 10; i++) { //Assign a value to a flexible array ps->a [i] = i; printf("%d ", ps->a [i]); } printf("\n"); printf("sizeof(ps) = %d\n", sizeof(ps));//Even if space is made for the flexible array, sizeof will record the size of the flexible array as 0 when calculating the size //If the size of flexible array a is not enough, you need to expand the space type_a* tmp = (type_a*) realloc(ps, sizeof(type_a) +20 * sizeof(int)); if (tmp == NULL) { printf("Expand space failed"); return -1; } else { ps = tmp; } for (i = 10; i < 20; i++) { ps->a [i] = i; printf("%d ", ps->a [i]); } printf("\n"); printf("sizeof(ps) = %d\n", sizeof(ps));//Even if space is made for the flexible array, sizeof will record the size of the flexible array as 0 when calculating the size //Destroy flexible array free(ps); ps = NULL; return 0; }
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-qsyaa4mp-163319053740) (assets / image-20211004112604-ax55la2. PNG)]
4. Pointer implementation method of flexible array
As can be seen from the above use case, the essence of flexible array is to use malloc to dynamically adjust the space size of the array.
Can we use pointers instead of the new concept of flexible array?
The answer is yes, but there are differences between the two methods. Let's look at the code directly and summarize it at the end.
#define _CRT_SECURE_NO_WARNINGS /* Pointer is used to realize the function similar to flexible array Pay attention to the difference between the two */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> typedef struct st_type2 { int i; int* a; }st_type2; int main() { //First, apply for space for structural variables st_type2* ps = (st_type2*) malloc(sizeof(st_type2)); ps->i = 0; //Then apply for space for pointer a in structure variable ps->a = (int*) malloc(sizeof(int) * 10); //Note the pointer type if (ps->a == NULL) { printf("%s\n", strerror(errno)); return -1; } int i = 0; for (i = 0; i < 10; i++) { ps->a [i] = i; printf("%d ", ps->a [i]); } printf("\n"); //The space pointed to by a is insufficient and needs to be expanded int* tmp = (int*) realloc(ps->a, sizeof(int) * 20); //Note the pointer type if (tmp == NULL) { printf("Capacity expansion failed\n"); return -1; } else { ps->a = tmp; } for (i = 10; i < 20; i++) { ps->a [i] = i; printf("%d ", ps->a [i]); } printf("\n"); //Destroy arrays and variables //Here, free is performed twice, once for free pointer a and once for free structure variable ps free(ps->a); ps->a = NULL; free(ps); ps = NULL; return 0; }
5. The difference between flexible array and pointer implementation
1. It is less likely to make mistakes when using flexible arrays.
Because you only need to use malloc for the whole structure variable once. The pointer method requires malloc twice, once for the variable and once for the address pointed to by the pointer.
Similarly, when space is released, the flexible array only needs to be free once, while the pointer method needs to be free twice.
2. Flexible arrays are more efficient.
I didn't understand the specific reason. For details, please refer to the following article.