概要

文件:src/core/ngx_array.h|ngx_array.c

名称:ngx_array_t

数据结构图

数据结构分析

特性/优缺点

  1. 在内存池中的小块内存中分配,即数组所占内存有限且内存池统一管理
  2. 内存空间连续,可索引访问,常量级,速度最快
  3. 动态扩容

使用

监听数组cycle->listening等

对比

  1. C数组:无法动态扩容
  2. STL的vector:

定义

  1. typedef struct {
  2. void *elts; // 指向实际数据存储区
  3. ngx_uint_t nelts; // 已用元素个数
  4. size_t size; // 单个元素大小
  5. ngx_uint_t nalloc; // 总共元素个数
  6. ngx_pool_t *pool; // 内存池指针
  7. } ngx_array_t;

操作

源码分析

  1. ngx_array_init与ngx_array_create的区别

    ngx_array_init:初始化,即成员变量赋初值,成员变量分配内存(若需要),但数组对象已定义即已分配结构体本身的内存。

    ngx_array_create:创建(含初始化),即为结构体申请内存,再执行ngx_array_init。

    用途不一致:新建数组时用ngx_array_create,重置时可用ngx_array_init

  2. ngx_array_destroy

    一般不用,或与ngx_array_create配套使用,若中途内存池为其他分配内存会无效。

    ngx_array_destroy并未真正释放内存,生效时也仅标识该内存可重用。即内存由内存池统一管理。

  3. 添加元素:ngx_array_push、ngx_array_push_n,看出数组特性:动态扩容、空间连续、大小固定

    返回地址,即先标识为元素添加内存空间,再使用返回值为空间填值。这种用法接触比较少见(一般会将地址作为参数传入) #反常识

    动态扩容:

    1. 扩容1/n个元素大小:所在内存块还有连续空间可供扩容
    2. 扩容2倍或2n个元素大小:所在内存块无法支持扩容

    此处实现看出数组特性:动态扩容、空间连续、大小固定、索引访问

  4. 指针操作难懂点
    ```c Node *n; // 数组元素类型 a->size = sizeof(Node); // 数组元素大小

n = ngx_array_push(a); // 返回插入元素地址 n->val = 123; // 赋值即表示已插入

int value = n->val; // 访问元素 value = (n+1)->val; // 访问下一元素,即指针移动1,表示内存移动sizeof(指针类型) value = n[1]->val; // 等价n[1] = (n+1)

  1. <a name="API"></a>
  2. ### API
  3. ```c
  4. ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
  5. void ngx_array_destroy(ngx_array_t *a);
  6. void *ngx_array_push(ngx_array_t *a);
  7. void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);

内部函数static

  1. static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size);

操作流程图

总结回顾