动态数组结构声明:
-
typedef struct {
-
void *elts; //数组首地址
-
ngx_uint_t nelts; //数组中元素个数
-
size_t size; //每个数组元素的大小
-
ngx_uint_t nalloc; //分配的内存总共能够容纳的元素个数
-
ngx_pool_t *pool; //用于分配内存的内存池
-
} ngx_array_t;
声明一个ngx_array_t结构之后的初始化:
在给定的内存池pool中分配n个大小为size的连续内存.
-
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:
从内存池p中动态分配一个动态数组结构体, 然后调用ngx_array_init来初始化这个结构体. 预分配内存大小为n * size
-
ngx_array_t *
-
ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
-
{
-
ngx_array_t *a;
-
-
a = ngx_palloc(p, sizeof(ngx_array_t));
-
if (a == NULL) {
-
return NULL;
-
}
-
-
if (ngx_array_init(a, p, n, size) != NGX_OK) {
-
return NULL;
-
}
-
-
return a;
-
}
在动态数组末尾压入元素的操作:
返回值是新压入元素的地址, 该元素由调用者初始化.
-
void *
-
ngx_array_push(ngx_array_t *a)
-
{
-
void *elt, *new;
-
size_t size;
-
ngx_pool_t *p;
-
// 预分配的内存空间已用完.
-
if (a->nelts == a->nalloc) {
-
-
/* the array is full */
-
-
size = a->size * a->nalloc;
-
-
p = a->pool;
-
// 预分配的内存空间末尾恰好是内存池中已分配内存的末尾. 且该内存池还可以
-
//容纳至少一个元素. 则直接在其后分配一个元素空间即可.
-
if ((u_char *) a->elts + size == p->d.last
-
&& p->d.last + a->size <= p->d.end)
-
{
-
/*
-
* the array allocation is the last in the pool
-
* and there is space for new allocation
-
*/
-
-
p->d.last += a->size;
-
a->nalloc++;
-
-
} else {
-
//否则需要需要在这篇内存池上重新分配一块内存, 扩容的内存空间为原来的两
-
//倍. 这种情况可能是在这个内存池上创建动态数组, 接着在这个内存池上另外分
-
//配其他的内存空间.
-
/* allocate a new array */
-
-
new = ngx_palloc(p, 2 * size);
-
if (new == NULL) {
-
return NULL;
-
}
-
-
ngx_memcpy(new, a->elts, size);
-
a->elts = new;
-
a->nalloc *= 2;
-
}
-
}
-
-
elt = (u_char *) a->elts + a->size * a->nelts;
-
a->nelts++;
-
-
return elt;
-
}
ngx_array_push_n和ngx_array_push类似, 不过可以一次新增加n个元素.
-
void * ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
动态数组的销毁.
-
void
-
ngx_array_destroy(ngx_array_t *a)
-
{
-
ngx_pool_t *p;
-
-
p = a->pool;
-
-
if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
-
p->d.last -= a->size * a->nalloc;
-
}
-
-
if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
-
p->d.last = (u_char *) a;
-
}
-
}
在使用动态数组的整个过程中, 如果会发生很多压入元素的操作, 而且数组元素个数不确定的情况下, 尽量不要使用动态数组所使用的内存池,
这样在动态数组使用完销毁时, 不会造成内存空间的浪费. 尽管最终内存池的内存会归还. 但是在内存池的使用期内不会造成内存的浪费.
阅读(2304) | 评论(0) | 转发(0) |