柔性数组--Linux内核结构体中的0长度数组

### 柔性数组作为其他结构体成员 在C99标准下,柔性数组可以被嵌套于另一个结构体之中。当一个结构体包含另一个具有柔性数组成员的子结构体时,需要注意内存分配方式以确保整个复合结构能够正确工作。 #### 定义带柔性数组成员的结构体并将其设为另一结构体的一部分 为了使柔性数组成为更大范围内的结构体组件之一,先定义含有柔性数组的基础结构: ```c typedef struct { size_t elements; int data[]; // 柔性数组成员 } FlexibleArrayStruct; ``` 接着,在更复杂的结构里加入上述基础结构作为一个字段: ```c struct ComplexStruct { char name[50]; float value; FlexibleArrayStruct flexArrMember; // 嵌入式柔性数组成员 }; ``` 然而,这种直接的方式并不适用于实际应用中因为`flexArrMember`本身没有足够的空间来存储其后的数据部分。因此,通常采用指针间接指向动态分配的空间实例化此类对象。 #### 正确的方法——通过指针访问含柔性数组结构体 下面展示了一个更为实用的例子,其中包含了如何初始化和操作这些复杂的数据结构: ```c #include <stdio.h> #include <stdlib.h> // 子结构体定义 typedef struct { size_t elements; int data[]; } SubStruct; // 主结构体定义 typedef struct { char label[20]; double price; SubStruct *sub_struct_ptr; // 用于保存柔性数组结构的指针 } MainStruct; void initialize(MainStruct **ms, const char* lbl, double prc, size_t elem_count); int main() { MainStruct *example = NULL; // 初始化函数调用 initialize(&example, "Product", 19.99, 3); printf("Label: %s\nPrice: %.2f\nElements:", example->label, example->price); for (size_t i = 0; i < example->sub_struct_ptr->elements; ++i) { printf(" %d", (*example).sub_struct_ptr->data[i]); } free(example->sub_struct_ptr); // 解除对柔性数组结构所占资源的占用 free(example); // 解除对外层结构所占资源的占用 return 0; } void initialize(MainStruct **ms, const char* lbl, double prc, size_t elem_count){ // 动态分配外层结构所需内存 *ms = malloc(sizeof(**ms)); if (!(*ms)) exit(-1); snprintf((*ms)->label, sizeof((*ms)->label), "%s", lbl); (*ms)->price = prc; // 计算内层结构及其后续柔性数组所需的总字节数量,并一次性完成分配 (*ms)->sub_struct_ptr = malloc( sizeof(SubStruct) + sizeof(int)*elem_count ); if (!(*ms)->sub_struct_ptr) {free(*ms); exit(-1);} (*ms)->sub_struct_ptr->elements = elem_count; // 给柔性数组赋初值 for(size_t idx=0 ;idx<elem_count;++idx){ ((*ms)->sub_struct_ptr->data)[idx]=idx+1; } } ``` 此代码片段展示了怎样安全有效地处理带有柔性数组成员的多级结构体[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值