STL union obj 解释
一个自由链表(free_list)在同一时刻,具备且仅具备如下功能之一:
1、作为一个自由链表指针,指向下一个自由链表
2、自身作为一块可用内存,供用户使用
由于如上用途不可能同时出现,故将obj定义为union,将free_list_link和client_data共享同一块内存来节省内存。
这句话是错误的:除了最后一个union其实是一个指针用来指向下一个方块的, 其它的其实都是用来直接分配给用户的
注意,这是链表,链表在内存中的分布是杂乱而不连续的,并非你所示的连续一段区域。 上文说道,一个obj结构,要不作为一块已被分配内存供用户使用,要不作为待分配区域存在于自由链表中。所以,自由链表中的每个块,都是指向下一个自由链表块,即理解为:
struct node{
node *next;
};
一旦这个自由链表块被分配给用户了,那么它就从自由链表中被移除了,不再被认为是一个自由链表块(由union的语义,从此它就是一块普通的,分配给用户的内存,直到被用户释放,它才会被再次加入自由链表中)
这句话并不妥当:其实用结构体也可以达到相同的效果啊
一旦内存分配完了,这块内存(即自由链表块)的指针就会被malloc()/new返回给用户,接下来保存指针的任务就交给用户了,我干嘛还在内存配置器里留着这货,多保存个指针不又把空间浪费掉了么。只有未分配的内存才能存在于自由链表中!
union obj
{
obj *free_list_link;
char client_data[1];
};
free_list_link是指向下一个内存区域,也是指向下一个list
对于client_data,这个数组就是指本块内存。
举个例子吧
//---------------------------------
union obj (OBJ1 ){}
//---------------------------------
这个union obj(OBJ1)中的free_list_link会被初始化,指向下一个内存域的开头,也是一个union obj结构。
对于union obj(OBJ1)中的client_data,其实就是本块内存的首地址,只是定义了一个一字节长度的数组。用这个数组的指针表示这块的内存的首地址。就像用数组定义一块数据区域一样的。你可以当作结构中没有free_list_link。
下面这个程序是个示例
#include <iostream>
using namespace std;
union obj
{
union obj *free_list_link;
char client_data[1];
};
int main(int argc, char const *argv[])
{
//假设这两个是要分配出去的内存。
char mem[100] = { 0 };
char mem1[100] = { 0 };
//现在是每一块内存的开始均是一个union node结构
//----------------------------------
//| union obj | ....................
// ----------------------------------
union obj *p1 = (union obj *)mem; //用一个变量表示这个结构
//p1->free_list_link 设置为下一个内存的起始段
p1->free_list_link = (union obj *)mem1 ;
//可以看到mem和client_data 两个指针值是一致的
cout <<"mem = " << (void *)mem << endl;
cout <<"p1->client_data = " << (void *)p1->client_data << endl;
//client_data只是为了简化本段内存的定义的,只是方便一些,
//可以使用(void *)p1表示本段内存,但是每次要转换,可能不方便吧,
//实际中可能也用不到
return 0;
}
- 从Trace和Debug来看条件编译(Conditional Compilation)
- 解码针对工业工程领域的网络攻击 Operation Ghoul「食尸鬼行动」
- EndpointAddress——不只是一个Uri[上篇]
- EndpointAddress——不只是一个Uri[下篇]
- ASP.NET Core中如影随形的”依赖注入”[上]: 从两个不同的ServiceProvider说起
- ASP.NET Core中如影随形的”依赖注入”[下]: 历数依赖注入的N种玩法
- ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存
- ASP.NET Core的路由[5]:内联路由约束的检验
- .NET Core跨平台的奥秘[下篇]:全新的布局
- Equation Group泄露文件分析
- ModelBinder——ASP.NET MVC Model绑定的核心
- 一句代码实现批量数据绑定[下篇]
- 三种属性操作性能比较:PropertyInfo + Expression Tree + Delegate.CreateDelegate
- 解密Myspace密码的姿势
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 给“小白”漫画+图示讲解MyBatis原理,就问香不香!
- webClientTest 编写单元测试类
- 关于gorm多表联合查询(left join)的小记
- UnicodeEncodeError: 'latin-1' codec can't encode character 'u2026' in position 30: ordinal not i...
- Oracle GoldenGate 19 Microservices完整高可用安装、配置与测试
- 爬虫小白:11.scrapy框架(六) _媒体管道
- R基于TCGA数据画生存曲线
- 爬虫小白:01-认识爬虫
- 04.BeautifulSoup使用
- 04.Xpath的使用
- 微服务[学成在线] day14:媒资管理
- Pandas 数据结构
- 微服务[学成在线] day15:媒资管理系统集成
- 时间序列
- 数据分组