柔性数组(柔性数组在结构体中只能存在一个)

本文介绍了C99中的柔性数组特性,包括结构中必须有其他成员、sizeof不包含柔性数组、动态分配内存及注意事项。同时对比了两种实现方式,强调了柔性数组在内存管理和访问速度上的优点。
摘要由CSDN通过智能技术生成

//————柔性数组(柔性数组在结构体中只能存在一个)

C99 中,结构体中的最后一个元素(成员变量)允许是未知大小的数组,这就叫做“柔性数组”成员。

//typedef struct st_type

//{

// int i;

// int a[0];//柔性数组成员

//}type_a;

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

//typedef struct st_type

//{

// int i;

// int a[];//柔性数组成员

//}type_a;

————1 柔性数组的特点:

1.结构中的柔性数组成员前面必须至少一个其他成员(两个成员及以上)。

2.sizeof 返回的这种结构体内存大小不包括柔性数组的内存。

3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大

 小,以适应柔性数组的预期大小。

//#include<stdio.h>

//struct S

//{

// int i;

// int a[0];//柔性数组成员

//};

//int main()

//{

// int n = sizeof(struct S);//大小不包括柔性数组的大小

// printf("%d\n", sizeof(n));//输出的是4

//  //struct S s;//此时创建的结构体s大小为4字节,只能存n,没有给arr开辟空间,是错误的。

// return 0;

//}

//————2 柔性数组的使用

代码1

//#include<stdio.h>

//#include<stdlib.h>

//struct S

//{

// int n;

// int arr[];//柔性数组成员

//};

//int main()

//{

// struct S* ps = (struct S*)malloc(sizeof(struct S) + 40);//40为柔性数组大小

// ps->n = 100;

// int i = 0;

// for (i = 0; i < 10; i++)

// {

//  ps->arr[i] = i;

//  printf("%d\n", ps->arr[i]);

// }

// struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 80);//ptr指向新开辟的空间时,把ptr赋值给了ps,即他们都指向realloc这块空间,

// if (ptr != NULL)//而free(ptr)就把此块空间给释放了,即ps就会变成野指针

// {

//  ps = ptr;//ptr的确也需要置成NULL;但是ptr赋值给了ps,即duips进行置成NULL即可

// }

// //释放

// free(ps);

// ps = NULL;

// return 0;

//}

这样柔性数组成员a,相当于获得了100个整型元素的连续空间。

————3 柔性数组的优势

上述的 type_a 结构也可以设计为:

代码2

//#include<stdio.h>

//#include<stdlib.h>

//struct S

//{

// int n;

// int* arr;

//};

//int main()

//{

// struct S* ps = (struct S*)malloc(sizeof(struct S) );//动态开辟结构体S(包含变量n和指针arr)

// //判断

// if (ps == NULL)

// {

//  return 1;//为空指针时,直接返回

// }

// ps->n = 100;//n和arr开辟都放在堆上,所以要让结构体开辟的空间也在堆上,保证设计思路的一致

// ps->arr = (int*)malloc(40);//此时转为int*类型是因为arr为int*

// //判断

// if (ps->arr == NULL)

// {

//  return 1;//为空指针时,直接返回

// }

// //使用

// int i = 0;

// for (i = 0; i < 10; i++)

// {

//  ps->arr[i]=i;

// }

// for (i = 0; i < 10; i++)

// {

//  printf("%d ", ps->arr[i]);

// }

// //扩容

// int* ptr=(int*)realloc(ps->arr,80);

// if(ptr == NULL)

// {

//  return 1;

// }  

// //

// //释放

// free(ps->arr);//先释放结构体中的数组,若先释放结构体,在释放arr,会使arr为野指针。若再不释放arr会导致内存泄漏

// free(ps);

// ptr= NULL;

// return 0;

//}

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

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

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给

用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你

不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好

了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

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

连续的内存有益于提高访问速度,也有益于减少内存碎片。
-----------------------------------
©著作权归作者所有:来自51CTO博客作者你会等待还是离开的原创作品,请联系作者获取转载授权,否则将追究法律责任
柔性数组——《初学C语言第56天》
https://blog.51cto.com/KKhahaha/9233760

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值