首先将数据结构上来
struct ngx_array_s { void *elts; ngx_uint_t nelts; size_t size; ngx_uint_t nalloc; ngx_pool_t *pool; };
为什么叫内存数组,就是因为该结构使用了ngx_pool_t 结构,既内存池的结构,介绍一下各个数据字段的意义
void *elts; 数组的分配内存的起始地址,就是指针。
nelts 为数组实际包含的元素数量,
size_t size 为单个元素的大小,
ngx_uint_t nalloc; 为其分配的元素个数
ngx_pool_t *pool;分配的内存大小
首先看一下初始化的源代码。
static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size) { /* * set "array->nelts" before "array->elts", otherwise MSVC thinks * that "array->nelts" may be used without having been initialized */ array->nelts = 0; array->size = size; array->nalloc = n; array->pool = pool; array->elts = ngx_palloc(pool, n * size); if (array->elts == NULL) { return NGX_ERROR; } return NGX_OK; }
下面就是方法。
// 创建一个新的数组容器
ngx_array_t *ngx_array_create(ngx_pool_t*p,ngx_uint_t n, size_t size);
// 销毁数组容器
voidngx_array_destroy(ngx_array_t *a);
// 将新的元素加入数组容器
void*ngx_array_push(ngx_array_t*a);
void*ngx_array_push_n(ngx_array_t*a,ngx_uint_t n);//返回n个元素的指针
这里需要注意的是,和之前的ngx_pool_cleanup_add一样,
ngx_array_push只是进行内存分配的操作,我们需要对返回的指针指向的地址进行赋值等操作来实现实际数组值的添加。
具体一点的push操作的实现为:
1. 首先判断 nalloc是否和nelts相等,即数组预先分配的空间已经满了,如果没满则计算地址直接返回指针
2. 如果已经满了则先判断是否我们的pool中的当前链表节点还有剩余的空间,如果有则直接在当前的pool链表节点中分配内存,并返回
3. 如果当前链表节点没有足够的空间则使用ngx_palloc重新分配一个2
4. 于之前数组空间大小的数组,然后将数据转移过来,并返回新地址的指针