摘要:在《C/C++ | 不会吧,不会吧,不会真的有人不知道柔性数组吧》总结中,通过比较定长数组,指针以及柔性数组之间的用法差异和优缺点来引入柔性数组的概念以及使用方法,本文承接上文,以问题的方式来理深入理解柔性数组。
关于构造函数的认知误区
问题 1:0长数组有什么好处❓
正解:
结构体最后使用0或1的长度数组的原因,主要是为了方便的管理内存缓冲区,如果你直接使用指针而不使用数组,那么,你在分配内存缓冲区时,就必须分配结构体一次,然后再分配结构体内的指针一次,(而此时分配的内存已经与结构体的内存不连续了,所以要分别管理即申请和释放)而如果使用数组,那么只需要一次就可以全部分配出来,反过来,释放时也是一样,使用数组,一次释放,使用指针,得先释放结构体内的指针,再释放结构体。还不能颠倒次序。其实就是分配一段连续的的内存,减少内存的碎片化。✔️
问题 2:0长数组占用内存空间吗❓
正解:0长数组不占用内存空间。✔️
分析: 0长数组占不占内存,我的理解是不占内存,因为在例子1中结构体SoftArray共有两个成员,int类型在前,char类型在后,通过sizeof(SoftArray)可以得到长度为4,恰好是一个仅仅是一个int类型的长度,所以不占内存,这个很好理解。
1// example 1
2#include
3using namespace std;
4struct SoftArray 5{
6 int len;
7 char data[0];
8};
9int main()10{
11 cout<sizeof(SoftArray);
12 return 0;
13}
14//output:4
细心的小伙伴可能会问了,如果在结构体SoftArray中,第一个成员变成char,第二个成员变成int,那是不是sizeof(SoftArray)的结果就是1了呢?做个实验来验一把。
1// example 2
2#include
3using namespace std;
4struct SoftArray 5{
6 char len;//注意了
7 int data[0];
8};
9int main()10{
11 cout<sizeof(SoftArray);
12 return 0;
13}
14//output:4
实验结果表明,sizeof(SoftArray)的结果仍然是4,那么你心中可能就开始疑惑了:不对呀,如果零长数组不占内存的话,结构体大小应该就是一个char的长度,结果应该为1呀。
这里的要点在于你是否熟悉结构体字节对齐的特点,一句话说就是编译器为了优化对结构体成员的访问总会在结构体中插入一些空白字节。当一个字节的char发现后面成员是一个四字节的int的时候,是会将字节扩充到4个字节的(填充3个字节)。关于字节对齐会在下篇c/c++系列中详解。
按照字节对齐的逻辑,sizeof(SoftArray)仍然为4的原因是由于填充了3个字节导致的,换句话说,如果我不填充,那么结果为1,即可证明0长数组不占内存。
1// example 3
2#include
3using namespace std;
4#pragma pack(1)
5struct SoftArray 6{
7 char len;
8 int data[0];
9};
10#pragma pack()
11int main()12{
13 cout<sizeof(SoftArray);
14 return 0;
15}
16output:1
这个代码很简单,就是在结构体上下用#pragma pack()包起来,这里的用用意是告诉编译器我要以1字节来对其。这样sizeof(SoftArray)输出的结果为1。证明完毕。
问题 3:数组和指针有区别吗❓
正解:除开数组作为参数时和指针没有区别之外,其他的还是有区别的。✔️
分析: 在零长数组中,char a[1]里面的a实际是一个常量,等于&a[0]。而char *b是有一个实实在在的指针变量b存在。所以,a=b是不允许的,而b=a是允许的。
问题 4:使用零长数组需要注意的点❓
正解:可能存在某些编译器不支持长度为0的数组的定义,在这种情况下,可以将它定义成char data [1],使用方法相同。
总结
零长数组好处多多。
零长数组不占用内存空间。
数组和指针是有区别的。
柔性数组中,data[0]与data[1]使用方法一样。
end
往期推荐
C/C++ | 不会吧,不会吧,不会真的有人不知道柔性数组吧
C/C++ | 头文件防卫,变量初始化夯实基础第一步
程序员,请停止学习框架!
喜欢本文点击关注点个在看哦
留个言吧