One minute to help you understand what is a flexible array!

What is a flexible array?

I believe that most bloggers have never heard of the concept of flexible arrays, but it does exist.

In C99, the last element of a structure (structure) is allowed to be an array of unknown size, which is called a flexible array member.

for example:

struct S
{
    
    
	int n;
	int arr[];//柔性数组成员
};

or it could be:

struct S
{
    
    
	int n;
	int arr[0];//柔性数组成员
};

Features of flexible arrays

1. There must be at least one other member in front of the flexible array member in the structure

For example, when you create a struct with a flexible array member, the struct member cannot have only one flexible array member:

struct Er
{
    
    
	int arr[];
};//error

In addition to flexible array members, structure members should contain at least one other non-flexible array member.

2. The size of the structure returned by sizeof does not include the memory of the flexible array

So, when you use sizeof to calculate the size of a structure with flexible array members, the calculated result does not include the flexible array members.

for example:

#include <stdio.h>
struct S
{
    
    
	int n;
	int arr[];//柔性数组成员
};
int main()
{
    
    
	printf("%d\n", sizeof(struct S));
	//结果为4
	return 0;
}

3. Use the malloc function to dynamically allocate memory for structures containing flexible array members, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array

For example, for this structure:

struct S
{
    
    
	int n;
	int arr[];//柔性数组成员
};

You want to use its flexible array members to store 5 integer elements, then you should open up space like this:

#include <stdio.h>
#include <stdlib.h>
struct S
{
    
    
	int n;
	int arr[];//柔性数组成员
};
int main()
{
    
    
	//开辟
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
	return 0;
}

insert image description here

Use of flexible arrays

We can use flexible arrays to achieve the following functions:

1. Requirements: Use a structure to encapsulate the number 100 and five numbers from 0 to 4.

2. The requirement is changed to: use a structure to encapsulate the number 100 and ten numbers from 0 to 9.

#include <stdio.h>
#include <stdlib.h>
struct S
{
    
    
	int n;
	int arr[];//柔性数组成员
};
int main()
{
    
    
	//开辟动态内存空间
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
	ps->n = 100;//将结构体中第一个元素赋值为100
	int i = 0;
	for (i = 0; i < 5; i++)
	{
    
    
		ps->arr[i] = i;
		//将柔性数组中下标为i的元素赋值为i
	}
	//调整所开辟的动态内存空间的大小
	struct S* ptr = realloc(ps, sizeof(struct S) + 10 * sizeof(int));
	if (ptr != NULL)//开辟成功
	{
    
    
		ps = ptr;
	}
	for (i = 5; i < 10; i++)
	{
    
    
		ps->arr[i] = i;
		//将柔性数组中下标为i的元素赋值为i
	}
	//释放开辟的动态内存空间
	free(ps);
	ps = NULL;
	return 0;
}

Note: The use of flexible arrays is inseparable from the knowledge of dynamically allocating memory.

Simulate the function of implementing flexible arrays

In fact, if we don't borrow flexible arrays, we can also achieve the above functions:

#include <stdio.h>
#include <stdlib.h>
struct S
{
    
    
	int n;
	int* arr;
};
int main()
{
    
    
	//开辟动态内存空间
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	ps->arr = (int*)malloc(5 * sizeof(int));
	ps->n = 100;//将结构体中第一个元素赋值为100
	int i = 0;
	for (i = 0; i < 5; i++)
	{
    
    
		ps->arr[i] = i;
		//将柔性数组中下标为i的元素赋值为i
	}
	//调整所开辟的动态内存空间的大小
	int* ptr = (int*)realloc(ps->arr, 10 * sizeof(int));
	if (ptr != NULL)//开辟成功
	{
    
    
		ps->arr = ptr;
	}
	for (i = 5; i < 10; i++)
	{
    
    
		ps->arr[i] = i;
		//将柔性数组中下标为i的元素赋值为i
	}
	//释放开辟的动态内存空间
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}

A flexible array is actually an array in the structure. To be precise, it is an array whose space size can be freely transformed. Then we define a pointer in the structure so that the space pointed to by the pointer can be freely transformed (that is, the pointer points to Dynamically allocated memory), this effect is also achieved.

Note: When releasing the dynamic memory space here, you need to first release the dynamic memory space pointed to by ps->arr, and then release the dynamic memory space pointed to by ps. If we release the dynamic memory space pointed to by ps first, then the space pointed to by ps->arr can no longer be found.

Advantages of flexible arrays

1. Convenient memory release

We can see that when using flexible arrays to solve this problem, we only need to release the dynamic memory once. When simulating and implementing flexible arrays, we need to release dynamic memory twice. The most important thing is that the order of these two memory releases cannot be reversed. If the release order is reversed, a piece of dynamically opened memory space cannot be released. Eventually lead to a memory leak.

2. It is beneficial to improve access speed and reduce memory fragmentation

In fact, when the first method uses flexible arrays to solve the problem, the space opened up in the memory is continuous:

insert image description here

The second method of simulating and implementing flexible arrays is almost like this when opening up memory:

insert image description here

It seems that it doesn't matter whether it is continuous or discontinuous when allocating memory, but do you know that there is a concept called memory fragmentation .

The more discontinuous memory allocations will generate more memory fragments, the more memory fragments, the lower our memory utilization , so we should try to avoid discontinuous memory allocations.

Second, when the CPU extracts data from the memory, it follows the principle of locality .

Locality principle: When the CPU accesses the memory, whether it is accessing instructions or accessing data, the accessed storage units tend to gather in a smaller continuous area.

Therefore, storing associated data together (that is, continuous storage) will increase the access speed of the CPU.

Guess you like

Origin blog.csdn.net/weixin_62976968/article/details/131352865