STL union obj 解释

时间:2019-02-16
本文章向大家介绍STL union obj 解释,主要包括STL union obj 解释使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://segmentfault.com/q/1010000006209284

一个自由链表(free_list)在同一时刻,具备且仅具备如下功能之一:

1、作为一个自由链表指针,指向下一个自由链表

2、自身作为一块可用内存,供用户使用

由于如上用途不可能同时出现,故将obj定义为union,将free_list_link和client_data共享同一块内存来节省内存。

这句话是错误的:除了最后一个union其实是一个指针用来指向下一个方块的, 其它的其实都是用来直接分配给用户的

注意,这是链表,链表在内存中的分布是杂乱而不连续的,并非你所示的连续一段区域。 上文说道,一个obj结构,要不作为一块已被分配内存供用户使用,要不作为待分配区域存在于自由链表中。所以,自由链表中的每个块,都是指向下一个自由链表块,即理解为:

struct node{
    node *next;
};

一旦这个自由链表块被分配给用户了,那么它就从自由链表中被移除了,不再被认为是一个自由链表块(由union的语义,从此它就是一块普通的,分配给用户的内存,直到被用户释放,它才会被再次加入自由链表中)

这句话并不妥当:其实用结构体也可以达到相同的效果啊

一旦内存分配完了,这块内存(即自由链表块)的指针就会被malloc()/new返回给用户,接下来保存指针的任务就交给用户了,我干嘛还在内存配置器里留着这货,多保存个指针不又把空间浪费掉了么。只有未分配的内存才能存在于自由链表中!

https://bbs.csdn.net/topics/390408109

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;
}