引言
当我们阅读 Redis 源码的时候,发现有些结构体会有如下一个数组元素:
1 | struct sdshdr5 |
思考一下的话,你会发现,我们在声明数组的时候如果不指定大小就需要声明的时候就得初始化,否则就会编译告警。但是恰恰上图所示的数组确可以编译通过。行吧,那么接下来要怎么赋值呢?
假如我们定义如下结构体:
1 | struct People |
- 法一 直接赋值
1 | struct People |
- 法二 变量赋值
1 | int main() |
方法二编译会报错 Initialization of flexible array member is not allowed ,也就是说是不运行这样赋值的。那么也就是说只能按照法一来赋值了吗?但是看 Redis 时并没有采用上述的方式,那么到底要如何使用呢?
柔性数组
以上数组就是柔性数组,什么是柔性数组?用最简单的话说就是不指定长度的数组,而且该数组只能作为结构体的最后一个成员且该成员不能是结构体的唯一成员。
好处
- 它可以按需分配内存
- 不占内存空间
- 内存连续
- 防止内存碎片
示例
1 | int main() |
大家可以思考一下输出。。。
1 | size of p is 8 |
我们发现,p 指向的结构体内存始终是 8 字节,而这个 8 字节就是 username 指针占用的内存大小,也就是说柔性数组不占内存,即使为它分配好内存。
对比指针
将 hobbies 换成指针不照样也可以嘛,如:
1 | struct People |
确实,但是相比柔性数组,指针的方式最大的弊端就是内存释放。也就是说,在释放结构体指针之前要先释放 hobbies 指针,否则就会引起内存泄露。除此之外,由于指针的方式声明的内存与结构体内存并不连续,一方面会造成内存碎片,一方面在访问结构体成员时也不十分便捷,所以才会有柔性数组的出现。