代码编织梦想

文章目录

1.柔性数组的概念

2.柔性数组的使用和特点

1.柔性数组不占用内存空间

2.有柔性数组的结构要用malloc分配空间

3.柔性数组的优势

1.方便内存释放

2.提高访问速度、减少内存碎片


1.柔性数组的概念

C99标准下结构中最后一个元素允许是未知大小的数组 ,这个数组就是柔性数组,也被称作变长数组。

        这里必须注意三点:第一,在结构体中定义的未知大小数组。 第二,该位置大小数组必须是结构体最后一个元素,该数组前面至少有一个元素。 举个例子,比如下方图片,arr就是柔性数组。 第三,数组名永远不会是指针,但是对于这个数组的大小,我们可以动态分配(下面会体现出来)。

2.柔性数组的使用和特点

1.柔性数组不占用内存空间

        对于编译器来说,柔性数组并不占用内存空间,可以用sizeof来验证。如下代码,运行后结果如图,是8,说明struct s这个结构体大小为8,而int类型和float类型的数据都是4个字节,根据结构体内存对齐规则,如果不计算arr的大小,结构体大小确实为8。

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

struct S
{
	int a;
	float b;
	int arr[];
};


int main()
{
	printf("%d ", sizeof(struct S));
}

2.有柔性数组的结构要用malloc分配空间

         包含柔性数组成员的结构要用malloc分配空间,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。如下,malloc分配给了s原本结构体的大小和4个int类型数据的大小,这4个int类型数据的大小就是分配给arr的,此时arr可用的是arr[0]到arr[3]。

        与此同时,由于是malloc分配,所以最后不用的时候要free掉。

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

struct S
{
	int a;
	float b;
	int arr[];//结构体最后一个元素允许是大小未知的,但是其前面至少有一个成员
};

int main()
{

	//开辟
	struct S* s = (struct S*)malloc(sizeof(struct S) + sizeof(int) * 4);
	if (!s)
	{
		printf("malloc fail!");
		exit(-1);
	}

	//使用
	s->a = 10;
	s->b = 5.5;
	for (int i = 0;i < 4;i++)
		s->arr[i] = i+1;

	printf("%d  %.2f\n", s->a,s->b);
	for (int i = 0;i < 4;i++)
	{
		printf("%d ", s->arr[i]);
	}

	//释放
	free(s);
	return 0;
}

        既然是“柔性数组”,那么其“”体现在哪里呢?比如上面的代码,arr只可以存放4个数据,但是现在需要存放10个数据,那么就要arr数组可以扩大容量,而柔性数组可以实现这个功能,其“柔”体现在这里。比如下面代码,调整的代码块,用realloc分配了s原本结构体的大小和10个int类型数据的大小,此时arr数组就可以存储10个数据。对新开辟的空间赋值,其运行结果如下图。

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

struct S
{
	int a;
	float b;
	int arr[];//结构体最后一个元素允许是大小未知的,但是其前面至少有一个成员
};


int main()
{
	//开辟
	struct S* s = (struct S*)malloc(sizeof(struct S) + sizeof(int) * 4);
	if (!s)
	{
		printf("malloc fail!");
		exit(-1);
	}

	//使用
	s->a = 10;
	s->b = 5.5;
	for (int i = 0;i < 4;i++)
		s->arr[i] = i+1;

	printf("%d  %.2f\n", s->a,s->b);
	for (int i = 0;i < 4;i++)
	{
		printf("%d ", s->arr[i]);
	}


	//调整
	struct S* ptr = (struct S*)realloc(s, sizeof(struct S) + 10 * sizeof(int));
	if (!ptr)
	{
		printf("realloc fail!");
		exit(-1);
	}
	else
	{
		s = ptr;
	}

	//使用
	for (int i = 4;i < 10;i++)
	{
		s->arr[i] = i+1;
	}
	for (int i = 4;i < 10;i++)
	{
		printf("%d ", s->arr[i]);
	}
	//释放
	free(s);
	return 0;
}

3.柔性数组的优势

        到这里,不免会有疑问,既然柔性数组是为了让数组容量可以变化,那么为什么不直接定义一个指针,然后动态分配内存呢?实际上,柔性数组比使用指针动态分配内存要好,一方面方便内存的释放,另一方面可以提高访问速度、减少内存碎片

1.方便内存释放

        如下代码,在开辟内存的时候,一方面要开辟结构体的空间(这里是为了模仿柔性数组,所以结构体也动态开辟),另一方面要开辟arr指向的数组的空间。释放的时候,既要释放结构体空间,又要释放arr指向数组的空间,比较麻烦。而上文中,使用柔性数组,可以直接一次性开辟、一次性释放,相较之下很方便。

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

struct S
{
	int a;
	float b;
	int* arr;
};

int main()
{
	//开辟
	struct S*  s = (struct S*)malloc(sizeof(struct S));
	if (!s)
	{
		printf("malloc fail!");
		exit(-1);
	}

	int* ptr = (int*)malloc(sizeof(int) * 10);
	if (!ptr)
	{
		printf("malloc fail!");
		exit(-1);
	}
	s->arr = ptr;

	//使用
	s->a = 10;
	s->b = 5.5;
	for (int i = 0;i < 10;i++)
	{
		s->arr[i] = i + 1;
	}

	printf("%d %.2f\n", s->a, s->b);

	for (int i = 0;i < 10;i++)
	{
		printf("%d ", s->arr[i]);
	}

	//释放
	free(s);
	s = NULL;
	free(ptr);
	ptr = NULL;

	return 0;
}

2.提高访问速度、减少内存碎片

         如下图,左边是结构体的内存示意,右边是堆区内存示意图。结合上面代码,在堆区内存中,开辟了一块空间存放结构体s,同时还要开辟另一块空间存放数组arr,但是这块空间位置随机的,可能是蓝色方框1、2、3、4中任意一个,也可能是其他地方,它和结构体并不连续,就导致结构体和数组arr中间的那一块空间,很难被利用,这块空间就被称为内存碎片

        但是用柔性数组就不胡有这样的问题,柔性数组 开辟的arr就是一个数组,而不是指针,如下图,这样不会存在内存碎片的问题。同时,由于数组就在结构体里面,所以a、b、arr数组在内存里是连续的,访问起来要快一些。而像上面的,arr是指针,多了一个找到arr物理地址的过程,相较之下要慢一点点。

 

         关于柔性数组,就介绍这么多啦!!!

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_65679465/article/details/127208933

c语言柔性数组-爱代码爱编程

struct test1 { char a; int c; }test1; 运行 printf("%d\n",sizeof(test1));后,结果为8(32位系统,下同),结构体中成员偏移量都是成员大小的

C语言柔性数组的用法-爱代码爱编程

1、概念 C柔性数组也叫0长度数组,GNU C 标准中支持柔性数组,标准C不支持柔性数组 2、用法 柔性数组使用方法如下:主要用于定义动态可变长数组 struct { int len; char buf[0]; } data; data.buf = malloc(BUF_SIZE); 3、与指针的差别 0长度数组不占用内存空间

C语言:0长度数组/可变数组/柔性数组-爱代码爱编程

C语言:0长度数组/可变数组/柔性数组 1. 0长度数组1.1 代码例子1.2 什么是0长度数组(可变数组/柔性数组)?1.3 用途1.4 用法1.5 优点1.6 缺点1.7 重点:数组名仅仅是一个符号1.8 GNU Document中 变长数组的支持2. 代码测试例(0长度的数组,定长数组,指针数组)3. 参考: 1. 0长度数组 C语言:

c语言柔性数组,C/C++柔性数组(可变长数组)-爱代码爱编程

8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? C/C++柔性数组(可变长数组) 定义 数组大小可变(待定)的数组C99标准之后引入了柔性数组的概念。在这之前,我们需要在结构体中存放一个动态长度的 字符串,一般都是定义一个char类型指针,使用该指针指向动态内存空间地址。但是这样操作不太方便, 而且定义的

C语言定义定长整型数组,C语言变长讯息定义:柔性数组-爱代码爱编程

C语言变长消息定义:柔性数组 在游戏前后端交换的过程中,经常会用到变成的消息体,因为有的内容的大小是位置的,例如一条微博,微博的内容大小是未知的。 一般的做法是定义一个char*类型的指针,然后指定其长度,代码如下: typedef struct{ unsigned len; char* pData; }Msg; 使用的时候是这样的:

【维生素C语言】第十五章 - 柔性数组(可变长数组)-爱代码爱编程

前言: 本篇将对C99标准中引入的新特性——柔性数组,进行讲解。并探讨柔性数组的优势,简单的介绍内存池的相关概念,来体会柔性数组的优点。 一、柔性数组介绍 📚 定义:柔性数组(Flexible Array),又称可变长数组。一般数组的长度是在编译时确定,而柔性数组对象的长度在运行时确定。在定义结构体时允许你创建一个空数组(例如:arr [ 0

(转)C语言柔性数组讲解-爱代码爱编程

先来看一个示例 #include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { int len = 10; printf("The struct's size is %d\n",sizeo

c语言——柔性数组_maggietzy的博客-爱代码爱编程

柔性数组——结构体的最后一个成员可以 被允许为是可变长(未知大小)的数组。其中arr[]也可以写为arr[0] struct S { int n; int arr[];//或int arr[0] //柔性数组成员 - 数组的大小是可以调整的 }; 结构体大小为4,只包含int n成员的大小 如下代码为开辟数组空间 int main() {

c语言变长数组(柔性数组)_c 变长数组-爱代码爱编程

变长数组(柔性数组) C99支持变长数组,定义时可以不指定数组长度,分配时再根据实际长度进行分配。 变长数组一般只能放在结构体的最后一个成员,在变长数组之前至少得有一个结构体成员且一个结构体只能有一个变长数组 变长数组

c语言 0长度数组/柔性数组_c语言定义一个全为零的数组-爱代码爱编程

一、什么是零长度数组 零长度数组就是长度为0的数组。 ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的。在ANSI C 中定义一个数组的方法如下: 类型 数组名[数组元素