[C language] 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));

结果
insert image description here
Why 8? This is related to the characteristics of flexible arrays:

  1. The size of such a structure returned by sizeof does not include memory for flexible arrays.

  2. 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.

  3. 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;
}

结果insert image description here

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;
}

结果
insert image description here

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?

  1. Method 1 mallocs once, frees once, i and arr are continuous, method 2 mallocs twice, frees twice, and the memory is not continuous.
  2. 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.
  3. 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.

Guess you like

Origin blog.csdn.net/Zhuang_N/article/details/128863104