Chinaunix首页 | 论坛 | 博客
  • 博客访问: 378924
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类: C/C++

2014-08-03 15:11:32

动态数组结构声明:

点击(此处)折叠或打开

  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;
声明一个ngx_array_t结构之后的初始化:
在给定的内存池pool中分配n个大小为size的连续内存.

点击(此处)折叠或打开

  1. static ngx_inline ngx_int_t
  2. ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
  3. {
  4.     /*
  5.      * set "array->nelts" before "array->elts", otherwise MSVC thinks
  6.      * that "array->nelts" may be used without having been initialized
  7.      */

  8.     array->nelts = 0;
  9.     array->size = size;
  10.     array->nalloc = n;
  11.     array->pool = pool;

  12.     array->elts = ngx_palloc(pool, n * size);
  13.     if (array->elts == NULL) {
  14.         return NGX_ERROR;
  15.     }

  16.     return NGX_OK;
  17. }
动态创建动态数组结构ngx_array_t:

从内存池p中动态分配一个动态数组结构体然后调用ngx_array_init来初始化这个结构体. 预分配内存大小为n * size

点击(此处)折叠或打开

  1. ngx_array_t *
  2. ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
  3. {
  4.     ngx_array_t *a;

  5.     a = ngx_palloc(p, sizeof(ngx_array_t));
  6.     if (a == NULL) {
  7.         return NULL;
  8.     }

  9.     if (ngx_array_init(a, p, n, size) != NGX_OK) {
  10.         return NULL;
  11.     }

  12.     return a;
  13. }

在动态数组末尾压入元素的操作:
返回值是新压入元素的地址, 该元素由调用者初始化.

点击(此处)折叠或打开

  1. void *
  2. ngx_array_push(ngx_array_t *a)
  3. {
  4.     void *elt, *new;
  5.     size_t size;
  6.     ngx_pool_t *p;
  7. // 预分配的内存空间已用完.
  8.     if (a->nelts == a->nalloc) {

  9.         /* the array is full */

  10.         size = a->size * a->nalloc;

  11.         p = a->pool;
  12. // 预分配的内存空间末尾恰好是内存池中已分配内存的末尾. 且该内存池还可以
  13. //容纳至少一个元素. 则直接在其后分配一个元素空间即可.
  14.         if ((u_char *) a->elts + size == p->d.last
  15.             && p->d.last + a->size <= p->d.end)
  16.         {
  17.             /*
  18.              * the array allocation is the last in the pool
  19.              * and there is space for new allocation
  20.              */

  21.             p->d.last += a->size;
  22.             a->nalloc++;

  23.         } else {
  24. //否则需要需要在这篇内存池上重新分配一块内存, 扩容的内存空间为原来的两
  25. //. 这种情况可能是在这个内存池上创建动态数组, 接着在这个内存池上另外分
  26. //配其他的内存空间.
  27.             /* allocate a new array */

  28.             new = ngx_palloc(p, 2 * size);
  29.             if (new == NULL) {
  30.                 return NULL;
  31.             }

  32.             ngx_memcpy(new, a->elts, size);
  33.             a->elts = new;
  34.             a->nalloc *= 2;
  35.         }
  36.     }

  37.     elt = (u_char *) a->elts + a->size * a->nelts;
  38.     a->nelts++;

  39.     return elt;
  40. }
ngx_array_push_n和ngx_array_push类似, 不过可以一次新增加n个元素.

点击(此处)折叠或打开

  1. void * ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)

动态数组的销毁.

点击(此处)折叠或打开

  1. void
  2. ngx_array_destroy(ngx_array_t *a)
  3. {
  4.     ngx_pool_t *p;

  5.     p = a->pool;

  6.     if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
  7.         p->d.last -= a->size * a->nalloc;
  8.     }

  9.     if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
  10.         p->d.last = (u_char *) a;
  11.     }
  12. }

在使用动态数组的整个过程中, 如果会发生很多压入元素的操作, 而且数组元素个数不确定的情况下, 尽量不要使用动态数组所使用的内存池,
这样在动态数组使用完销毁时, 不会造成内存空间的浪费. 尽管最终内存池的内存会归还. 但是在内存池的使用期内不会造成内存的浪费.


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