当前位置: 首页 > news >正文

C语言学习-24-柔性数组

目录

一、自由抒发

二、offsetof宏函数

1、作用

2、头文件

3、定义

4、参数介绍

三、实验模拟

1、测试代码

2、实验效果

四、优点与缺点

1、柔性数组的优点

2、 柔性数组的缺点


一、自由抒发

最近在摸索PG数据库源码时,发现一种之前没有用到过的C语言特性-柔性数组,它允许在结构体的末尾定义一个长度未知的数组。此特性比较适合需要动态管理内存的场景。

二、offsetof宏函数

再讲柔性数组数组之前,我们先了解一下offsetof宏函数,对于后面的实验有帮助。

1、作用

计算结构体中某个成员相对于结构体起始地址的偏移量(以字节为单位)。

2、头文件

#include <stddef.h>

3、定义

size_t offsetof(type, member);

4、参数介绍

参数描述
type结构体类型。
member结构体中的成员名称。

三、实验模拟

1、测试代码

#define TEST_STUDENT_NAME_LEN 8
#define TEST_STUDENT_DESC_LEN 16typedef struct MyStudentSt
{char     Name[TEST_STUDENT_NAME_LEN];int      Sex;int      Age;char     Desc[];
}MyStudentSt;Status main()
{LOG_LEVEL = Debug;MyStudentSt *Student = (MyStudentSt *)MyMalloc(sizeof(MyStudentSt) + sizeof(char) * TEST_STUDENT_DESC_LEN);char        *Desc    = NULL;LOG_FORMAT(Debug,"MyStudentSt      = %lu\n",sizeof(MyStudentSt));LOG_FORMAT(Debug,"MyStudentSt.Name = %lu\n",offsetof(MyStudentSt,Name));LOG_FORMAT(Debug,"MyStudentSt.Sex  = %lu\n",offsetof(MyStudentSt,Sex));LOG_FORMAT(Debug,"MyStudentSt.Age  = %lu\n",offsetof(MyStudentSt,Age));LOG_FORMAT(Debug,"MyStudentSt.Desc = %lu\n",offsetof(MyStudentSt,Desc));strcpy(Student->Desc,"Sun Moon");Desc = (char *)Student + offsetof(MyStudentSt,Desc);LOG_FORMAT(Debug,"MyStudentSt.Desc = '%s'\n",Student->Desc);LOG_FORMAT(Debug,"Desc             = '%s'\n",Desc);free(Student);Student = NULL;return SUCCESS_FLAG;
}

2、实验效果

2025-08-27 15:11:33.102338-P[112005]-T[112005]-[Debug]-main               : MyStudentSt      = 16
2025-08-27 15:11:33.102623-P[112005]-T[112005]-[Debug]-main               : MyStudentSt.Name = 0
2025-08-27 15:11:33.102631-P[112005]-T[112005]-[Debug]-main               : MyStudentSt.Sex  = 8
2025-08-27 15:11:33.102635-P[112005]-T[112005]-[Debug]-main               : MyStudentSt.Age  = 12
2025-08-27 15:11:33.102638-P[112005]-T[112005]-[Debug]-main               : MyStudentSt.Desc = 16
2025-08-27 15:11:33.102641-P[112005]-T[112005]-[Debug]-main               : MyStudentSt.Desc = 'Sun Moon'
2025-08-27 15:11:33.102645-P[112005]-T[112005]-[Debug]-main               : Desc             = 'Sun Moon'

MyStudentSt结构体计算字节数为16,也就是没有计算柔性数组Desc,需考虑字节对齐,我这边是4的倍数,所以正好,没有自动补齐。

打印出每个参数的起始地址的偏移量。

获取到Desc的起始地址的偏移量,Student + 得到的偏移量 = Student->Desc地址,从打印结果一致来看,我们的代码逻辑也是正确的。

Desc = (char *)Student + offsetof(MyStudentSt,Desc);

这里 (char *)Student类型转换很关键,不转化的话加的就不是offsetof算出的字节数了,而是offsetof(MyStudentSt,Desc) * sizeof(MyStudentSt)个字节了。

四、优点与缺点

1、柔性数组的优点

优点详细说明
内存连续性结构体和数组成员在内存中连续存储,提高缓存局部性和访问效率
单次内存分配只需要一次malloc/free操作,简化内存管理
减少内存碎片避免多次分配造成的内存碎片问题
无指针开销节省存储指针所需的内存(通常4-8字节)
访问简便直接使用struct->array[index]语法,无需多级解引用
更好的缓存性能连续内存布局有利于CPU缓存预取,减少缓存未命中
代码更简洁所有相关数据在一个结构体中,代码更易理解和维护
精确内存控制可以精确计算所需内存大小,避免过度分配

2、 柔性数组的缺点

缺点详细说明
标准要求高需要C99或更新标准,不支持C89/C90
编译器兼容性某些老旧编译器可能不支持此特性
C++兼容性问题C++标准不完全支持C风格的柔性数组
使用限制严格必须是结构体的最后一个成员,不能有多个柔性数组
不能栈上分配必须使用动态内存分配,不能创建栈上的实例
需要手动计算大小必须正确计算分配内存的大小,容易出错
缺乏边界检查C语言不提供数组边界检查,需要开发者自行维护
调试工具支持有限某些调试器可能无法正确显示柔性数组内容
静态分析挑战一些静态分析工具可能难以处理柔性数组的模式
调整大小困难需要重新分配整个结构体来调整数组大小

http://www.dtcms.com/a/355454.html

相关文章:

  • 科技守护古树魂:古树制茶行业的数字化转型之路
  • TikTok 在电脑也能养号?网页端多号养号教程
  • 损失函数,及其优化方法
  • [Ai Agent] 从零开始搭建第一个智能体
  • 麒麟操作系统挂载NAS服务器
  • 搜维尔科技核心产品矩阵涵盖从硬件感知到软件渲染的全产品供应链
  • 12KM无人机高清图传通信模组——打造未来空中通信新高度
  • hintcon2025 Pholyglot!
  • 辅助驾驶出海、具身智能落地,稀缺的3D数据从哪里来?
  • kubernetes-ubuntu24.04操作系统部署k8s集群
  • 吃透 OpenHarmony 资源调度:核心机制、调度策略与多设备协同实战
  • Linux(二) | 文件基本属性与链接扩展
  • ManusAI:多语言手写识别的技术革命
  • SLF4J和LogBack
  • Linux 命令使用案例:文件和目录管理
  • 从0开始学习Java+AI知识点总结-27.web实战(Maven高级)
  • Python Imaging Library (PIL) 全面指南:PIL基础入门-图像滤波与处理技术
  • python自动化测试工具selenium使用指南
  • AS32S601抗辐照MCU在商业卫星EDFA系统中的应用研究
  • 基于 Selenium 和 BeautifulSoup 的动态网页爬虫:一次对百度地图 POI 数据的深度模块化剖析
  • 033 日志
  • 硬件三人行--运算基础篇
  • 怎样将Word转成高质量的DITA
  • 【涂鸦T5】1. 环境搭建和demo
  • 量化策略布林带解读
  • Java Spring(1)- Spring基础
  • AI提升SEO关键词效果新策略
  • PostgreSQL【应用 04】加解密扩展 pgcrypto 使用实例(加密、导出、导入、解密流程说明)
  • 信息技术发展
  • Flink Redis广播方案