[置顶] 解析变长结构体的用法和优点
2017-05-14 10:08
274 查看
变长结构体:
在接触变长结构体之前,以为会是一个很难理解的东西,但是这其实算是C里面的一种技巧吧,优点是:分配了一段连续的内存,防止内存碎片化以及方便内存的管理。使用变长结构体的格式如下:
struct Test { .... int a; .... char b[0]; };
重点是结构体的最后一个成员
char b[0],是个空数组。在我们不知道结构体内的某个成员大小是多少的时候,我们在最后一个成员放置了一个空数组,这样做的好处就是,我们直接用结构体指针申请空间(
sizeof(struct) + 给空数组申请的空间),就完成了动态分配。
这里可能读者会有一个疑惑,那就是指针也同样完成这个任务,为什么不用指针呢。这里我们就用一个例子来说明:
#include <iostream> using namespace std; #include <cstring> #include <stdlib.h> typedef struct { int a; char b[0]; }Empty; typedef struct { int x; char *y; }Ptr; int main() { //变长结构体申请内存 Empty *p_array = (Empty *)malloc(sizeof(Empty) + 100); //可以看到这里直接申请了变长结构体大小的空间再加100字节,这100字节就相当于是给char b[0]用的了 //常规方式申请内存,先申请结构体的,再申请指针的 Ptr *p_ptr = (Ptr *)malloc(sizeof(Ptr)); p_ptr->y = (char *)malloc(100); //初始化malloc申请的内存 memset(p_array, 0, sizeof(p_array)); memset(p_ptr, 0, sizeof(p_ptr)); memset(p_ptr->y, 0, 100); //拷贝字符串并输出 strcpy(p_array->b, "test"); strcpy(p_ptr->y, "test"); cout << p_array->b << endl; cout << p_ptr->y << endl; //释放空间 cout << "--------------------------" << endl; if(p_array != NULL) { cout << "1.释放变长结构体的空间" << endl; free(p_array); p_array = NULL; } cout << "--------------------------" << endl; if(p_ptr->y != NULL) { cout << "1.释放指针申请的空间" << endl; free(p_ptr->y); p_ptr->y = NULL; if(p_ptr != NULL) { cout << "2.释放结构体的空间" << endl; free(p_ptr); p_ptr = NULL; } } return 0; }
两者相比较,得出以下主要结论:
变长结构体的内存是连续的(严谨的说是虚拟内存),而常规方法的不是,所以变长结构体只需释放一次空间,而常规方法需要释放两次。
并且我们使用
sizeof查看两个结构体的大小会发现,
Empty结构体的大小为4字节,而
Ptr的大小为8字节,可以得出
char b[0]是不占内存空间的。
最后还有需要注意的一点就是,有些编译器可能不支持
char b[0]这样的写法,可以换成
char b[1],用法还是一样的,只是这时的结构体大小变成了
4 + 1 + 3 = 8字节,最后那个3字节是由于内存对齐填补上的。
相关文章推荐
- [置顶] FloatingActionButton属性、用法,以及解析并解决sdk25以上只隐藏不显示的问题
- marquee的详细用法解析
- delphi中的XML解析控件TXMLDocument的用法
- shell学习之-sed用法解析
- SQL聚合函数功能和用法解析
- 模板特化用于协议解析的一种用法
- extern "C"用法解析
- 完全解析MySQL数据库中Show命令用法(网上资料整理)
- ajaxPro.dll用法解析
- ANSI C中取得结构体字段偏移值的惯用法
- ANSI C中取得结构体字段偏移值的惯用法
- 解析xml的脚本函数,与C#用法是不一样的
- struts 里关于checkbox与radio的 用法解析
- 无间断滚动marquee的详细用法解析
- 让批处理被wsh解析的优点
- 解析ifstream 与ofstream的用法
- 无间断滚动marquee的详细用法解析
- ANSI C中取得结构体字段偏移值的惯用法
- 完全解析MySQL数据库中Show命令用法
- native2ascii用法解析