【C语言】—— 柔性数组

一、柔性数组的定义

1、柔性数组的定义
在c99中提到,在一个结构体中,结构体的最后一个元素可以是一个未知大小的数组,这个就叫做柔性数组成员。

2、柔性数组表示

 #include
 
    struct  S
    {
           int a;
           char arr[];//柔性数组
    }
    //有些编译器支持这样书写柔性数组
    struct S
    {
           int a;
           char arr[0];//柔性数组
    }

3、柔性数组的特点

  • 结构中的柔性数组成员前面必须至少一个其他成员。
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
    【C语言】—— 柔性数组_第1张图片

4、柔性数组的使用

struct S
{
	int a;
	char  arr[];//柔性数组
};
int main()
{
	//为结构体动态开辟空间,前半部分开的空间大小是4个字节,后半部分是给柔性数组arr开辟的空间
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 100 * sizeof(char));
	struct S* ptr = NULL;
	ps->a = 20;
	strcpy(ps->arr, "abcdefg");

	printf("%d\n", ps->a);
	printf("%s\n", ps->arr);

	//若是觉得柔性数组开辟100字节不够使用,可以用realloc为其重新开辟空间
	ptr = (struct S*)realloc(ps, sizeof(struct S) + 200 * sizeof(char));
	if (ptr != NULL)
		ps = ptr;


	free(ps);
	ps = NULL;
	return 0;
}

5、柔性数组的优势
下面我们先来看一段代码

struct S
{
	int a;
	char arr[];//柔性数组
};

struct B
{
	int a;
	char* arr;
};

void Test1()
{

	//为结构体动态开辟空间,前半部分开的空间大小是4个字节,后半部分是给柔性数组arr开辟的空间
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 100 * sizeof(char));
	struct S* ptr = NULL;
	ps->a = 20;
	strcpy(ps->arr, "abcdefg");

	printf("柔性数组:%d\n", ps->a);
	printf("柔性数组:%s\n", ps->arr);

	//若是觉得柔性数组开辟100字节不够使用,可以用realloc为其重新开辟空间
	ptr = (struct S*)realloc(ps, sizeof(struct S) + 200 * sizeof(char));
	if (ptr != NULL)
		ps = ptr;


	free(ps);
	ps = NULL;	
}

void Test2()
{
	//先为结构体B开辟空间,为8个字节
	struct B* ps = (struct B*)malloc(sizeof(struct B));
	char* ptr = NULL;
	//此时为结构体中的指针arr动态开辟空间
	ps->arr = (char*)malloc(sizeof(char)* 100);

	ps->a = 20;
	strcpy(ps->arr, "abcdef");

	printf("指针:%d\n", ps->a);
	printf("指针:%s\n", ps->arr);

	//若是觉得指针指向的空间开辟100字节不够使用,可以用realloc为其重新开辟空间
	ptr = (char*)realloc(ps->arr, 200 * sizeof(char));
	if (ptr != NULL)
		ps->arr = ptr;

	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
}


int main()
{
	Test1();
	Test2();
	return 0;

}

【C语言】—— 柔性数组_第2张图片
在这里我们可以看到,在结构体中定义一个指针或是一个柔性数组实现的功能是一样的,也能达到一样的效果,为什么还有有柔性数组的概念呢,这是因为柔性数组有着它无法被替代的优势,那下面我们来分析一下柔性数组的优势:
【C语言】—— 柔性数组_第3张图片
优势一:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
优势二:有利于访问速度.
从图中我们可以看到使用柔性数组的结构体开辟的空间是连续的,但是使用指针的结构体开辟的空间是不连续的,这样多次使用之后,就会造成许多内存碎片,另外连续的内存有益于提高访问速度,也有益于减少内存碎片。

你可能感兴趣的:(C语言学习)