flexible array
1. What is a flexible array
In C99, the last element in a structure is allowed to be an array of unknown size, which is called a "flexible array" member.
struct S
{
int i;
char c;
char arr[0];//柔性数组//也可以把0省略掉
};
2. Features of flexible arrays
Let's first calculate the size of the structure containing the flexible array. Take the above as an example.
printf("%",sizeof(struct S));
结果
Why 8? This is related to the characteristics of flexible arrays:
-
The size of such a structure returned by sizeof does not include memory for flexible arrays.
-
A flexible array member in a structure must be preceded by at least one other member. We found that the size of the structure is exactly 8 without the flexible array. If there is no member before the flexible array, then the size of the structure is 0, and the structure does not exist.
-
Structures containing flexible array members use the malloc() function for dynamic allocation of memory, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array.
例子
struct S
{
int i;
char arr[0];
};
int main()
{
struct S* p = (struct S*)malloc(sizeof(struct S) + sizeof(char) * 10);
printf("%d", sizeof(struct S));
free(p);
p = NULL;
return 0;
}
结果
3. The use of flexible arrays
struct S
{
int i;
char arr[0];
};
int main()
{
struct S* p = (struct S*)malloc(sizeof(struct S) + sizeof(char) * 10);
if (NULL == p)
{
perror("malloc");
return 1;
}
//对柔性数组赋值
int i = 0;
for (i = 0; i < 10; i++)
{
*(p->arr + i) = i + 97;//97是a的ASCII码值
}
//对柔性数组打印
for (i = 0; i < 10; i++)
{
printf("%c ", *(p->arr + i));
}
free(p);
p = NULL;
return 0;
}
结果
4. Advantages of flexible arrays
There is also a second approach to the above example, and the advantages can be obtained through comparison
struct S
{
int i;
char *arr;//改为指针
};
int main()
{
struct S* p = (struct S*)malloc(sizeof(struct S));
if (NULL == p)
{
perror("malloc");
return 1;
}
p->arr = (char*)malloc(sizeof(char) * 10);
if (NULL == p->arr )
{
perror("malloc");
return 1;
}
//对柔性数组赋值
int i = 0;
for (i = 0; i < 10; i++)
{
*(p->arr + i) = i + 97;//97是a的ASCII码值
}
//对柔性数组打印
for (i = 0; i < 10; i++)
{
printf("%c ", *(p->arr + i));
}
free(p->arr );
p->arr = NULL;
free(p);
p = NULL;
return 0;
}
This method can also achieve the desired effect, but the first method is better, why?
- Method 1 mallocs once, frees once, i and arr are continuous, method 2 mallocs twice, frees twice, and the memory is not continuous.
- Method 1 is not easy to make mistakes and is convenient for memory release, only need to be released once. Its members have no application space and need not be released, while the members of method 2 have application space and need to be released again.
- Method 2, the more malloc times, the more memory fragments, and the lower the utilization rate of memory space; at the same time, method 1 is conducive to access speed due to continuous memory.