解析变长结构体的用法和优点

c语言可变长度结构体定义,可变大小结构体如何定义详解 一、背景工作中,在通信协议中常常看到TLV格式数据,不同的type id对应的字符串长度大小不一样。那么该怎么去定义一个结构体去管理这些数据呢?怎么去定义一种可变大小的结构体?本文将讲解如何定义可变大小结构体。二、定义可变大小结构体1、方法一:使用指针1 typedef struct_S_HB_TIME_REPORT_INFO2 {3 uint16_t msg_id;4 uint16_t msg_... 阅读详情

变长结构体:


在接触变长结构体之前,以为会是一个很难理解的东西,但是这其实算是C里面的一种技巧吧,优点是:分配了一段连续的内存,防止内存碎片化以及方便内存的管理。

使用变长结构体的格式如下:

struct Test
{
  ....
  int a;
  ....
  char b[0];
};

重点是结构体的最后一个成员char b[0],是个空数组。在我们不知道结构体内的某个成员大小是多少的时候,我们在最后一个成员放置了一个空数组,这样做的好处就是,我们直接用结构体指针申请空间(sizeof(struct) + 给空数组申请的空间),就完成了动态分配。

这里可能读者会有一个疑惑,那就是指针也同样完成这个任务,为什么不用指针呢。这里我们就用一个例子来说明:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdlib.h>
typedef struct
{
    int a;
    char b[0];
}Empty;
typedef struct
{
    int x;
    char *y;
}Ptr;
int main()
{
    //变长结构体申请内存
    Empty *p_array = (Empty *)malloc(sizeof(Empty) + 100);  //可以看到这里直接申请了变长结构体大小的空间再加100字节,这100字节就相当于是给char b[0]用的了
    //常规方式申请内存,先申请结构体的,再申请指针的
    Ptr *p_ptr = (Ptr *)malloc(sizeof(Ptr));
    p_ptr->y = (char *)malloc(100);
    //初始化malloc申请的内存
    memset(p_array, 0, sizeof(p_array));
    memset(p_ptr, 0, sizeof(p_ptr));
    memset(p_ptr->y, 0, 100);


    //拷贝字符串并输出
    strcpy(p_array->b, "test");
    strcpy(p_ptr->y, "test");
    cout << p_array->b << endl;
    cout << p_ptr->y << endl;

    //释放空间
    cout << "--------------------------" << endl;
    if(p_array != NULL)
    {
        cout << "1.释放变长结构体的空间" << endl;
        free(p_array);
        p_array = NULL;
    }
    cout << "--------------------------" << endl;
    if(p_ptr->y != NULL)
    {
        cout << "1.释放指针申请的空间" << endl;
        free(p_ptr->y);
        p_ptr->y = NULL;
        if(p_ptr != NULL)
        {
            cout << "2.释放结构体的空间" << endl;
            free(p_ptr);
            p_ptr = NULL;
        }
    }
    return 0;
}

两者相比较,得出以下主要结论:
变长结构体的内存是连续的(严谨的说是虚拟内存),而常规方法的不是,所以变长结构体只需释放一次空间,而常规方法需要释放两次。

并且我们使用sizeof查看两个结构体的大小会发现,Empty结构体的大小为4字节,而Ptr的大小为8字节,可以得出char b[0]是不占内存空间的。

最后还有需要注意的一点就是,有些编译器可能不支持char b[0]这样的写法,可以换成char b[1],用法还是一样的,只是这时的结构体大小变成了4 + 1 + 3 = 8字节,最后那个3字节是由于内存对齐填补上的。

结构体或类定义中对变长成员的处理 <br />对于一个结构体,头部信息固定,成员节点变长的,可以采用下面的定义方式:<br />1. 数组<br />typdef struct _stHeadInfo /*头部*/<br />{<br /> int version;<br /> int magic_num;<br /> int req_count;<br /> int res_count;<br /> char cgiinfo[0];<br />} stHeadInfo __attribute__((__aligned__(4)));<br 阅读详情

相关推荐

ABAP 结构体全景解析:从 DDIC 到 RAP 与 OData 的数据骨架

本文深入解析了ABAP结构体在SAP系统中的核心作用与设计方法。文章首先阐明结构体作为数据组织骨架的重要性,然后详细介绍了DDIC中的结构体类型分类、技术/语义属性、复用机制及增强方式。重点分析了Flat/Nested/Deep三种结构形态的特点及适用场景,特别指出数据库表与经典视图必须使用扁平结构的约束。通过实际案例展示了结构体在SAP Gateway OData服务和RAP模型中的应用价值,并提供了基于ADT的现代维护方法。全文系统性地阐述了如何设计稳健的结构体以支撑服务建模、系统扩展和长期运维。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1747

变长结构体

文章目录什么是变长结构体定义变长结构体变长结构体实例参考资料 什么是变长结构体 变长结构体是由gcc扩展的一种技术,它是指其最后一个成员的长度不固定(flexible array member,也叫柔性数组)。 使用范围:数据长度不固定,例如协议对接中有固定的头结构体,数据结构体不固定。 定义变长结构体 struct MyData { int nLen; char data[0]...

mayue_web的博客 1796

人工智能之语言领域 自然语言处理 第六章 情感分析

情感分析(Sentiment Analysis),又称意见挖掘(Opinion Mining),旨在自动识别和提取文本中表达的主观情感、态度或情绪。从用户评论到社交媒体,从产品反馈到政治舆情,情感分析已成为企业决策、品牌监控和人机交互的关键技术。本章将深入介绍情感分析的层级结构、核心技术、主流模型,并通过社交媒体舆情实战案例完整演示分析与可视化流程。层级目标示例词级(Word-level)判断单个词的情感倾向“好” → 正面;“差” → 负面句级(Sentence-level)判断整个句子的情感极性。

咚咚王者的博客 857

C语言结构体

- 今天复习一下struct,顺便挖掘一下以前没注意的小细节: 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。 结构体定义: 第一种:只有结构体定义[cpp] view plain copy print?struct stuff{          char job[20];

Innocence_y的博客 4072

Ubuntu 24.04 高效部署Slurm集群:从零到生产环境实战

本文提供了一份在Ubuntu 24.04 LTS系统上从零开始部署生产级Slurm高性能计算集群的完整实战指南。内容涵盖网络配置、Munge安全认证、Slurm核心组件安装与配置,并深入讲解了cgroups资源隔离、NFS共享存储、配置无感知模式等生产环境优化技巧,最后通过实例演示如何提交与管理Slurm作业,帮助用户构建高效、稳定的计算平台。

weixin_29213655的博客 565

DeepSpeed Zero3 Offload实战:从GCC版本检查到环境配置的完整避坑指南

本文是一份针对DeepSpeed Zero3 Offload部署的完整避坑指南。针对训练中常见的`AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam`报错,文章深入剖析了其根源在于GCC编译器版本过低。指南提供了从系统GCC版本深度探查、安全启用高版本GCC环境,到DeepSpeed一致性安装验证的全链路实战方案,旨在帮助用户构建稳定的大模型训练环境。

weixin_29070721的博客 474

深入浅出变长结构体

原文链接 深入浅出变长结构体 1、 问题的引出 项目中用到数据包的处理,但包的大小是不固定的,其长度由包头的2字节决定。比如如下的包头:88 0f 0a ob cd ef 23 00 。长度由头2个字节880f决定,考虑字节序,转为0f88,转为10进制3976个字节的包长度。 这个时候存储包的时候,一方面可以考虑设定包的大小固定:如4K=4*1024=4096个字节,因为最大包长不可能超过4k,但该方法的有缺陷,存在一种极端就是包最小仅含包头不含数据域,此时包为8个字节,浪费了4096-8 =4088个字

后而来者 570

配置cts performance最优范围

这里写自定义目录标题cts例如此案例中,我们多测几次,发现Measured frame rate 的平均值为average=(380+389+380+371)/4=380 cts by VinterYoung Expected achievable frame rates for OMX.MTK.VIDEO.DECODER.HEVC video/hevc 1280x720: [75.0, 262.0]. Measured frame rate: [380.5645006622224, 389.3983545

o343196469的博客 1319

C++Q&A(二) 变长数组和变长结构体是什么

声明:Q&A系列的文章是我在平时自己遇到的或者看到的一些问题,本着再小的问题也需要有人解答的想法,将这些问题和答案整理出来。 欢迎和我讨论问题,同时也欢迎转载Q&A系列的文章。 第一个问题 什么是变长数组 变长数组是C99中的新加入的特性,要理解这个变长数组很简单,只需一段代码就可以了。 int a[10]; //定长数组 int b[n]; //变长数组,n可以是任何正

waponx的专栏 2446

从零开始:使用COLMAP与OpenMVS构建高精度三维Mesh模型

本文为零基础新手提供了使用COLMAP与OpenMVS构建高精度三维Mesh模型的完整实战指南。详细介绍了从环境配置、数据采集黄金法则,到COLMAP稀疏与稠密重建、OpenMVS网格生成与纹理映射的每一步操作,并分享了关键的避坑技巧与参数调优建议,帮助读者从二维照片中成功重建出属于自己的三维模型。

metal的博客 506

CTF——流量分析题型整理总结

我见过的流量分析类型的题目总结: 一,ping 报文信息 (icmp协议) 二,上传/下载文件(蓝牙obex,http,难:文件的分段上传/下载) 三,sql注入攻击 四,访问特定的加密解密网站(md5,base64) 五,后台扫描+弱密码爆破+菜刀 六,usb流量分析 七,WiFi无线密码破解 八,根据一组流量包了解黑客的具体行为 例题: 一,ping 报文信息 (icm...

小锤队长的博客 5万+

C++变长结构体

C99允许。结构体最后使用0或1的长度数组的原因,主要是为了方便的管理内存缓冲区,如果你直接使用指针而不使用数组,那么,你在分配内存缓冲区时,就必须分配结构体一次,然后再分配结构体内的指针一次,(而此时分配的内存已经与结构体的内存不连续了,所以要分别管理即申请和释放)而如果使用数组,那么只需要一次就可以全部分配出来,(见下面的例子),反过来,释放时也是一样,使用数组,一次释放,使用指针,得先释放结...

追求卓越 1864

数学建模 种群竞争模型 学习笔记

模型背景 应用场景 种群竞争模型 例如 s1=0.5,则表示对于供养甲的资源来讲,单位数量的乙的消耗为单位数量的甲的0.5倍,即表示乙对于该资源的占有能力是甲的0.5倍(即竞争力弱) 仿真结果及分析 (1)设置自然增长率 r1=r2=1 (2)改变自然增长率 r1=r2=0.3 (3)修改甲和乙的最大容量 n1=10000, n2=100 (4)修改甲和乙的初始数量 x1=10, x...

Test_tju的博客 2028

可变长度的数组(定义数组时长度为0)

       在标准C和C++中,长度为0的数组是被禁止使用的。不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在这儿,它表示的完全是另外的一层意思,这个特性是不可移植的,所以,如果你致力于编写可移植,或者是稍稍需要跨平台的代码,这些伎俩最好还是收起来的好 用途 :长度为0的数组的主要用途是为了满...

世间所有的相遇都是久别重逢 6476

2025年“区块链技术”职业院校技能大赛赛后复盘与总结(必看)

记录一次2025年“区块链技术”职业院校技能大赛的参加经验总结与赛后复盘

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 1993

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Python二进制数据解析实战:从C结构体到construct库应用

二进制数据解析是处理底层数据交换、网络协议和嵌入式系统通信的基础技术。其核心原理在于将连续的字节序列按照预定义的内存布局和数据类型进行解释与重构。这项技术的价值在于能够高效、准确地处理非文本格式的原始数据,避免手动计算偏移量和处理字节序带来的错误与低效。在嵌入式开发、逆向工程和网络协议分析等应用场景中,开发者常需解析由C语言结构体直接序列化而来的数据块。Python生态为此提供了多种工具,例如标准库的struct模块用于简单格式,ctypes模块便于与C代码交互,而第三方库如construct和cstruc

weixin_29268267的博客 288

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

结构体和联合体的大小,结构体内存对齐的原因、规则以及柔性数组

以下代码运行环境为64位平台下的VS2013 结构体的大小: 例:typedef struct fun { int a; char b; double c; short d; }; int main() { int ret = sizeof(Fun); cout << "ret= " << ret <<"\n"<< endl; system

scmuzi18的博客 827

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C语言网络通信:从定长到变长消息协议的设计与实现

在网络通信与进程间通信中,自定义消息协议是解决数据打包、传输与解析问题的核心机制。其基本原理是在无序的字节流中定义明确的消息边界,通过序列化与反序列化确保数据在不同系统间的可靠交换。从工程实践角度看,协议设计需处理粘包拆包、字节序对齐及缓冲区管理等关键技术点,这对于嵌入式系统、后端服务及高性能中间件开发至关重要。本文以C语言为例,通过从定长协议到变长协议的演进,深入探讨了如何通过结构体打包、长度字段引入及头部增强来构建健壮的通信框架,并自然融入了网络编程和字节流处理等热词,为开发者提供了从基础到进阶的完整实

weixin_33997389的博客 400

c结构体中的 柔性数组

出处:http://blog.youkuaiyun.com/stand1210/article/details/52459372 开发C代码时,经常见到如下类型的结构体定义: 1 2 3 4 5 typedefstruct  list_t{ structlist_t *next; structlist_t

nawuyao的博客 445

source insight4.0 内核源码 skb sk_buff 结构体 struct_group 不识别问题解决

struct_group 通过宏创造了一种对开发者很友好的“语法糖”,但它所依赖的匿名结构体、变长参数等特性,恰恰踩中了 Source Insight 这种非编译型、基于模式匹配的解析器的多个“软肋”。这也就是为什么即便添加了 C.tom 规则,有时仍无法完美解决所有解析问题的根本原因——因为工具的核心处理逻辑,在面对这种“宏魔法”时存在天然的局限性。

小狗爱吃黄桃罐头的博客 199

C语言结构体详解:从数据打包到内存对齐的完整指南

在C语言编程中,数据结构是组织和管理信息的核心。结构体作为一种复合数据类型,其原理在于将不同类型的数据成员封装成一个逻辑整体,从而解决数据分散管理带来的关联性弱、操作繁琐等问题。这一技术价值在于显著提升了代码的清晰度、可维护性和数据安全性,是实现从零散变量到清晰数据模型跨越的关键。在工程实践中,结构体广泛应用于嵌入式系统开发、操作系统内核、网络协议栈以及各类数据结构的实现中。本文聚焦于结构体的定义、指针操作、内存对齐等核心概念,并结合学生管理系统等实际场景,深入解析其应用与常见问题,特别是针对STM32等嵌

weixin_34232744的博客 370

GCC扩展语法解析:范围表示与零长度数组

C语言作为系统级编程语言,其编译器扩展功能在工程实践中具有重要价值。GCC作为主流编译器,通过语法扩展实现了更灵活的内存管理和代码优化。范围表示法(case 2...8)简化了多条件分支处理,零长度数组则突破了标准C的数组限制,实现变长结构体等高级特性。这些扩展在嵌入式开发、协议栈实现等场景中广泛应用,通过__attribute__机制还能控制内存对齐和段分配。理解GCC扩展语法不仅能提升代码效率,也是深入Linux内核开发的基础。本文重点解析范围语法和零长度数组的实现原理与工程实践。

weixin_36444661的博客 548

C语言结构体详解:从数据封装到内存对齐与工程实践

在C语言编程中,数据封装是构建复杂程序的基础。通过将不同类型的数据成员组合成一个自定义数据类型,结构体实现了数据的逻辑聚合,从根本上保障了数据一致性。其核心原理在于将分散的变量整合为单一实体,通过点操作符和箭头操作符进行成员访问。这一技术价值在于显著提升了代码的可维护性和可读性,是迈向结构化编程的关键。在应用场景上,结构体广泛应用于数据记录管理、配置参数定义、网络协议封包以及构建链表、树等高级数据结构。本文以学生信息管理为例,深入探讨了结构体的定义、初始化、内存对齐优化以及动态内存分配等工程实践,并指出了结

weixin_33831196的博客 306

# 遍历结构体_二叉树迭代 / 递归遍历模板和思路解析

二叉树遍历相信大家对于二叉树的定义以及结构,在本科《数据结构与算法》课程中或者在其他同学的博客中有所了解。在此,不在过多地回顾课本理论知识。我们编码语言主要为C++,如下是二叉树在C++中类的表现形式,这边使用的是 struct 结构体,在C++中类和结构体的区别在于不标志 public , private 以及 protected 时, 成员变量和成员函数是 public 还是 private ...

weixin_36466165的博客 208
上一篇: epoll的边缘触发(ET)和水平触发(LT)
下一篇: 指针作为参数传入函数的陷阱
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值