C语言—柔性数组

news/2025/1/12 21:38:04/


C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;

有些编译器会报错无法编译可以改成:

typedef struct st_type
{int i;int a[];//柔性数组成员
}type_a;

柔性数组的特点

  • 结构中的柔性数组成员前面必须至少一个其他成员。
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
printf("%d\n", sizeof(type_a));//输出的是4

柔性数组的使用

int main()
{int i = 0;type_a* p = (type_a*)malloc(sizeof(type_a) + 100 * sizeof(int));//业务处理p->i = 100;for (i = 0; i < 100; i++){p->a[i] = i;}for (i = 0; i < 100; i++){printf("%d",p->a[i]);}struct S* ptr = (struct S*)realloc(p, 200 * sizeof(int));if (ptr != NULL){p = ptr;ptr = NULL;}//...free(p);
}

柔性数组的优势

//代码2
typedef struct st_type
{int i;int *p_a;
}type_a;
type_a *p = (type_a *)malloc(sizeof(type_a));
p->i = 100;
p->p_a = (int *)malloc(p->i*sizeof(int));
//业务处理
for(i=0; i<100; i++)
{p->p_a[i] = i;
}
//释放空间
free(p->p_a);
p->p_a = NULL;
free(p);
p = NULL;

这里两份代码都是用malloc来开辟结构体变量空间是因为像开辟在堆区

上述 代码1 代码2 可以完成同样的功能,但是 方法1 的实现有两个好处:

**第一个好处是:**方便内存释放

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给 用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你 不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好 了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

**第二个好处是:**这样有利于访问速度.

连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正 你跑不了要用做偏移量的加法来寻址)


http://www.ppmy.cn/news/1443413.html

相关文章

《QT实用小工具·三十九》仿 Windows10 画图3D 的颜色选择器, 但更加强大

1、概述 源码放在文章末尾 该项目实现了仿 Windows10 画图3D 的颜色选择器&#xff0c;功能更加丰富更加强大。 项目部分代码如下所示&#xff1a; import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import QtGraphicalEffects 1.15Item {id…

C++中的时间相关处理

time.h 在C11之前&#xff0c;C 程序员通常使用 C 语言标准库中的时间和日期函数来处理时间&#xff0c;这些函数的精度通常只有秒级别。这些传统的 C 语言 API 包括 time.h 头文件中定义的函数&#xff0c;如 time(), gmtime(), localtime(), mktime() 等。这些函数使用 time…

C++里的new

C里的new&#xff1a; new开辟的空间在堆上&#xff0c;而一般声明的变量存放在栈上。当在局部函数中new出一段新的空间&#xff0c;该段空间在局部函数调用结束后仍然能够使用&#xff0c;可以用来向主函数传递参数。new出来的是一段空间的首地址。所以一般需要用指针来存放这…

AngularJS中文手册前半部分学习

AngularJS 简介 AngularJS的中文参考手册 AngularJS的使用 AngularJS 是一个JS框架&#xff0c;通过指令(ng-directives)扩展了HTML&#xff0c;且通过表达式绑定数据到HTML&#xff0c;用于开发单一页面应用程序&#xff08;SPAs&#xff1a;Single Page Applications&…

六.音视频编辑-创建视频过渡-概述

引言 目前我的应用已经实现了视频的编辑&#xff0c;音频的混合处理。随着时间的推进&#xff0c;两个不同场景的视频快速的切换&#xff0c;其中没有任何过渡效果。通常画面在时间轴上出现明显的变化时&#xff0c;两个场景间会使用一些动画的过渡效果。比如渐隐&#xff0c;…

Android如何使用XML自定义属性

1、定义 在res/values文件下定义一个attrs.xml文件&#xff0c;代码如下: 2、使用 在布局中使用&#xff0c; 示例代码如下&#xff1a; 3、获取 最终来到这里&#xff1a;

Android Binder——APP中AIDL解析(二十)

上一篇我们最后运行了项目,并完成了跨进成通信。这里我们就来以 getTitleText() 为例分析一下调用流程。 一、调用流程 首先,我们在 bindService 成功回调 onServiceConnected 中,通过 IMyAidlInterface.Stub.asInterface() 获取 Binder 的代理对象。对应方法在 IMyAidlInt…

应用在隔离的IGBT模块中的光电耦合器

IGBT(Insulated Gate Bipolar Transistor)&#xff0c;绝缘栅双极型晶体管&#xff0c;是由BJT(双极型三极管)和MOS(绝缘栅型场效应管)组成的复合全控型电压驱动式功率半导体器件, 兼有MOSFET的高输入阻抗和GTR的低导通压降两方面的优点。GTR饱和压降低&#xff0c;载流密度大&…