Chinaunix首页 | 论坛 | 博客
  • 博客访问: 870272
  • 博文数量: 87
  • 博客积分: 3324
  • 博客等级: 中校
  • 技术积分: 1003
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 11:37
文章分类

全部博文(87)

文章存档

2014年(3)

2013年(5)

2012年(21)

2011年(13)

2010年(7)

2009年(9)

2008年(4)

2007年(14)

2006年(11)

分类: C/C++

2012-10-31 11:19:01

ngx_list_t顾名思义,看起来好像是一个list的数据结构。这样的说法,算对也不算对。因为它符合list类型数据结构的一些特点,比如可以添加元素,实现自增长,不会像数组类型的数据结构,受到初始设定的数组容量的限制,并且它跟我们常见的list型数据结构也是一样的,内部实现使用了一个链表。

 

那么它跟我们常见的链表实现的list有什么不同呢?不同点就在于它的节点,它的节点不像我们常见的list的节点,只能存放一个元素,ngx_list_t的节点实际上是一个固定大小的数组。

 

在初始化的时候,我们需要设定元素需要占用的空间大小,每个节点数组的容量大小。在添加元素到这个list里面的时候,会在最尾部的节点里的数组上添加元素,如果这个节点的数组存满了,就再增加一个新的节点到这个list里面去。

 

好了,看到这里,大家应该基本上明白这个list结构了吧?还不明白也没有关系,下面我们来具体看一下它的定义,这些定义和相关的操作函数定义在src/core/ngx_list.h|c文件中。

 

 

 

typedef struct {

    ngx_list_part_t  *last;

    ngx_list_part_t   part;

    size_t            size;

    ngx_uint_t        nalloc;

    ngx_pool_t       *pool;

} ngx_list_t;

 

last: 指向该链表的最后一个节点。

part: 该链表的首个存放具体元素的节点。

size: 链表中存放的具体元素所需内存大小。

nalloc: 每个节点所含的固定大小的数组的容量。

pool: list使用的分配内存的pool

 

好,我们在看一下每个节点的定义。

 

typedef struct ngx_list_part_s  ngx_list_part_t;

struct ngx_list_part_s {

    void             *elts;

    ngx_uint_t        nelts;

    ngx_list_part_t  *next;

};

 

elts: 节点中存放具体元素的内存的开始地址。

nelts: 节点中已有元素个数。这个值是不能大于链表头节点ngx_list_t类型中的nalloc字段的。

next: 指向下一个节点。

 

 

我们来看一下提供的一个操作的函数。

 

ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);

 

该函数创建一个ngx_list_t类型的对象,并对该list的第一个节点分配存放元素的内存空间。

 

pool: 分配内存使用的pool

n: 每个节点固定长度的数组的长度。

size: 存放的具体元素的个数。

返回值: 成功返回指向创建的ngx_list_t对象的指针,失败返回NULL

 

void *ngx_list_push(ngx_list_t *list);

 

该函数在给定的list的尾部追加一个元素,并返回指向新元素存放空间的指针。如果追加失败,则返回NULL

 

static ngx_inline ngx_int_t

ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size);

 

该函数是用于ngx_list_t类型的对象已经存在,但是其第一个节点存放元素的内存空间还未分配的情况下,可以调用此函数来给这个list的首节点来分配存放元素的内存空间。

 

那么什么时候会出现已经有了ngx_list_t类型的对象,而其首节点存放元素的内存尚未分配的情况呢?那就是这个ngx_list_t类型的变量并不是通过调用ngx_list_create函数创建的。例如:如果某个结构体的一个成员变量是ngx_list_t类型的,那么当这个结构体类型的对象被创建出来的时候,这个成员变量也被创建出来了,但是它的首节点的存放元素的内存并未被分配。

 

总之,如果这个ngx_list_t类型的变量,如果不是你通过调用函数ngx_list_create创建的,那么就必须调用此函数去初始话,否则,你往这个list里追加元素就可能引发不可预知的行为,亦或程序会崩溃!

阅读(2875) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~