Basic syntax of C language Chapter 11 - flexible array

Why do we need flexible arrays?

#define MAXLEN 1024
struct kd_node
{
	struct kd_node*left;
	struct kd_node*right;
	int dim;
	unsigned long long data[MAXLEN];
};

In this code, in order to store data, an unsigned long long array with a length of 1024 is applied. If the array length is much smaller than MAXLEN. This design will be an extremely waste of space. If MAXLEN is too small, we need a large array length, which is unreasonable. Therefore, in order to meet our needs, flexible arrays, also known as variable length arrays, can be selected according to specific needs, so they have the attractive feature of variable length or flexibility~~~

Lushan true face of flexible array

struct sd_node 
{
	int num;
	int size;
	char data[];
};

Flexible arrays are arrays of undetermined size

In C language, you can use a structure to generate a flexible array. In the design of a structure, the last item is an array, and its length is 0 (or no length is given). This array is a flexible array

Note: global array or local array cannot be defined in this way

Details of flexible arrays

In strcut SD_ In the node structure, data is only an identifier and does not occupy storage space. therefore

sizeof(strcut sd_node)=   8

Purpose: arrays with length of 0 are mainly structures with variable length

Usage: at the end of the structure, declare an array with length 0 to make the structure variable. For the compiler, the array with length 0 does not occupy space at this time, because the array name itself does not occupy space, it is only an offset, and the symbol of the array name itself represents an immutable address constant. We can dynamically allocate the size of this array

int main()
{
	const char str[] = "Hello Love_Hoeny_You";
	struct sd_node*sp = (struct sd_node*)malloc(sizeof(struct sd_node) + 100);
	sp->num = 5;
	sp->size = 21;
	strcpy(sp->data, str);
	free(sp);
	system("pause");
	return 0;
}

Illustration:

Advantages: this method is more efficient than the method of dynamic allocation by declaring a pointer variable in the structure

Pointer packet:

#include <stdlib.h>
#include <stdio.h>

struct data_buff
{
	int num;   //Block number
	int size;  //Data length
	char*data;
};

int main()
{
	const char str[] = "Hello Love_Honey_You";
	struct data_buff*ptr_buff = (struct data_buff*)malloc(sizeof(struct data_buff));
	if (ptr_buff == NULL)
	{
		exit(1);
	}
	ptr_buff->size = strlen(str)+1; 
	ptr_buff->data = (char*)malloc(sizeof(char)*ptr_buff->size);
	if (ptr_buff->data == NULL)
	{
		exit(1);
	}
	strcpy(ptr_buff->data, str);
	printf("OVER\n");
	free(ptr_buff->data);
	free(ptr_buff);
	ptr_buff = NULL;
	system("pause");
	return 0;
}

Note: PTR should be released to the_ Buff - > data, and then release ptr_buff. If the order is reversed, the PTR will be lost_ Buff - > address stored in data memory, causing memory leakage. And PTR was released_ Buff, release PTR again_ Buff - > data, the compiler will report an error~~~

Variable length data buffer:

#include <stdio.h>
#include <stdlib.h>

struct data_buff
{
	int num;  //Block number
	int len;  //Data length
	char data[];
};

int main()
{
	const char str[] = "Love_Honey_You~~~";
	struct data_buff*p_buff = (struct data_buff*)malloc(sizeof(struct data_buff) + sizeof(char)*(strlen(str) + 1));
	if (p_buff == NULL)
	{
		exit(1);
	}
	strcpy(p_buff->data, str);
	free(p_buff);
	system("pause");
	return 0;
}

Disadvantages: in the structure, the array with length 0 must be declared at the end, and there are certain restrictions on the design structure type

Note: if the structure is generated through dynamic allocation methods such as calloc, malloc or realloc, the corresponding space shall be released when it is not needed

sizeof calculates the size of a structure with a flexible array

#include <stdio.h>
#include <stdlib.h>

struct data_buff
{
	int num;  
	int len;  
	char data[];  //data is an identifier and does not occupy space
};
int main()
{
	struct data_buff test = { 1, strlen(), "My_Love_Girl" }; //Flexible array on stack
  
	int len = sizeof(struct data_buff);

	system("pause");
	return 0;
}

Note: sizeof calculates the number of bytes occupied by the data type and is determined at compile time

Dynamically create a two-dimensional array

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int cos = 0;  //that 's ok
	int row = 0;  //column
	scanf("%d%d", &cos, &row);
	int**s = (int **)malloc(sizeof(int*)*cos);
	for (int i = 0; i < cos; i++)
	{
		s[i] = (int *)malloc(sizeof(int)*row);
	}
	for (int i = 0; i < cos; i++)
	{
		for (int j = 0; j < row; j++)
		{
			s[i][j] = i + j;
			printf("%d ", s[i][j]);
		}
		printf("\n");
	}
	for (int i = 0; i < cos; i++)
	{
		free(s[i]);
	}
	free(s);
	system("pause");
	return 0;
}

 

s stores the address of the first element in the pointer array. The first element in the pointer array stores the address of the first element in the first row integer array. Different pointer types have different + 1 capabilities. Each element of the two-dimensional array can be easily accessed through the subscript operator

For example, create an array int {arr[3] [4] on the stack, & arr represents the address of the entire two-dimensional array, and & S represents the address of the space where the address of the first element in the pointer array is stored

The difference between arr[2][3] and s[2][3]

(1) Arr represents the address of the first line, arr+2 ------ "represents the offset to the third line, and * (arr+2) represents the address of the first element in the third line

*(arr+2)+3 -- "indicates the address of the fourth element in the third line --" * (* (arr+2)+3) - "indicates the fourth element in the third line itself

(2) s represents the address of the first element in the pointer array, and s+2 -- "represents the address offset to the third element in the pointer array

*(s+2) - "represents the address of the first element in the third line, * (s+2)+3" - "represents the address of the fourth element in the third line

*(* (s+2)+3) represents the fourth element in the third line itself

(3) arr+1 skips 16 bytes, while s+1 skips only 4 bytes

Note: the difference between dynamic two-dimensional arrays and two-dimensional arrays on the stack is that dynamic two-dimensional arrays are not necessarily continuous in memory. They are connected through pointers, so they are only logically continuous. The two-dimensional array on the stack is continuous both in logic and memory

Keywords: C Back-end

Added by joseph on Thu, 06 Jan 2022 02:31:27 +0200