C++变长结构体

变长结构体,其实真正意义上并不是结构体的大小可变,而是使用结构体中的变量代表一个地址,从而访问超出结构体大小范围的数据

如下两个结构体:

using node = struct node
{
    int a;
    int b;
}
using nodes = struct nodes
{
    int nodeNums;
    node *array[2];
}

现在创建5个node结构体变量

std::vector<node> allNode;

for(int i=0;i<5;++i)
    allNode.append(new node);

首先计算nodes结构体加上这5个结构体指针的长度

decltype{allNode.size()} length=sizeof(nodes)+sizeof(node *)*allNode.size();

创建此长度的缓冲区

std::vector<char> buffer;
buffer.resize(length);

将此字符数组强制转换为nodes结构体

nodes *n=reinterpret_cast<node *>(buffer.data());

此时就可以为结构体的变量赋值了

n->nodeNums=5;
for(int i=0;i<n->nodeNums;++i)
    n->array[i]=reinterpret_cast<node *>(&allNode[i]);



在C语言中,**变长结构体(Flexible Array Member)** 是一种允许结构体最后一个成员是未指定大小的数组的特性。它常用于实现可变长度的数据结构,例如网络协议中的数据包、动态缓冲区等。 --- ### 一、变长结构体的定义 C99 标准引入了“柔性数组成员”(Flexible Array Member)的概念,允许结构体最后一个成员声明为 `[]`,即不指定大小。 #### 示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct Packet { int type; size_t length; char data[]; // 柔性数组成员 }; ``` --- ### 二、使用变长结构体 由于柔性数组成员不占用存储空间,因此结构体的大小不包括该数组。我们需要手动为结构体和数组分配足够的内存。 #### 示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct Packet { int type; size_t length; char data[]; // 变长数组 }; int main() { const char *message = "Hello, Flexible Array Member!"; size_t msg_len = strlen(message) + 1; // 分配足够空间:结构体 + 数据 struct Packet *pkt = malloc(sizeof(struct Packet) + msg_len); if (!pkt) { perror("malloc failed"); return 1; } pkt->type = 1; pkt->length = msg_len; strcpy(pkt->data, message); printf("Packet Type: %d\n", pkt->type); printf("Packet Length: %zu\n", pkt->length); printf("Packet Data: %s\n", pkt->data); free(pkt); return 0; } ``` --- ### 三、注意事项 1. **柔性数组必须是结构体最后一个成员**。 2. **不能直接声明结构体变量**,只能通过指针动态分配内存。 3. **不能使用 `sizeof` 获取数组大小**,必须单独记录长度。 4. **内存必须手动管理**,使用 `malloc` 和 `free`。 5. **C++不支持柔性数组成员**,但可以用 `char data[0]` 或 `std::vector` 替代。 --- ### 四、应用场景 - 网络数据包解析(如IP、TCP头) - 动态字符串结构体 - 内存池管理 - 日志记录器 - 高性能数据结构 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值