我总结了一下用指针和用变长结构体的区别:
1.在位置方面:指针可以放在任何地方,但是变长结构体的变长部分一定要放在结构体的最后。
2.在内存占用方面:指针会占一个指针的大小的内存空间,但是变长数组是不占内存的,它只是一个占位符。
3.在内存布局方面:指针指向的内存和结构体的内存可以是不连续的,但是变长部分和结构体的内存必须是连续。
4.在内存释放方面:使用指针,就要先释放指针所指的内存在释放整个结构体的内存,否则会照成内存泄露。
但是使用变长结构体直接释放整个结构体的空间就可以了
5.一个限制:指针可以用在C++的类中,但是变长结构体就不可以了。因为有些编译器会将一些额外的信息放在类的最后,
比如vptr或者虚基类的内容,使用了变长的类,就会把这部分的值改变,这种行为是未定义的,谁也不知道会发生什么。
(以上引用别人的,我觉得很好啊)
柔性数组(Flexible Array)也叫伸缩性数组,也就是变长数组
这种代码结构产生于对动态结构体的需求,
比如我们需要在结构体中存放一个动态长度的字符串时,就可以用柔性数组。
C99使用不完整类型来实现柔性数组,标准形式如下:
标识占位符(不占结构struct的空间)
C99使用不完整类型实现柔性数组成员,标准形式是这样的:
struct test
{
int a;
double b;
char c[];
};
c同样不占用test的空间,只作为一个符号地址存在,而且必须是结构体的最后一个成员。柔性数组成员不仅可以用于字符数组,还可以是元素为其它类型的数组:
示例代码:
#include
using namespace std;
struct A{
int q;
int w[0];
};
int main()
{
int n=5;
cout << sizeof(A) << endl;
A*p=(A*)new (char[sizeof(A)+n]);
for(int i=0;i
w[i]=i;
}
for(int i=0;i
w[i]<<" ";
}
delete p;
return 0;
}
结果:
4
0 1 2 3 4
4
0 1 2 3 4
类中带有该种结构体:
#include
using namespace std;
struct A{
int q;
int w[0];
};
class B{
public:
A r;
int c;
};
int main()
{
int n=5;
cout << sizeof(B) << endl;
B *p=(B*)new (char[sizeof(B)+n]);
for(int i=0;i
r.w[i]=i;
}
for(int i=0;i
r.w[i]<<" ";
}
delete p;
return 0;
}
结果正常;
但交换B中数据成员位置:
会崩溃,符合最开始第五条的说明,使用codeblock
MinGW下
会崩溃,符合最开始第五条的说明,使用codeblock
MinGW下
#include
using namespace std;
struct A{
int q;
int w[0];
};
class B{
public:
int c;
A r;
};
int main()
{
int n=5;
cout << sizeof(B) << endl;
B *p=(B*)new (char[sizeof(B)+n]);
for(int i=0;i
r.w[i]=i;
}
for(int i=0;i
r.w[i]<<" ";
}
delete p;
return 0;
}