nginx开发-数据结构

ngx_str_t

typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;

ngx_string(str)


初始化一个字符串为str,str必须为常量字符串, 一般只用于声明字符串变量时顺便初始化变量的值。


ngx_null_string


声明变量时,初始化字符串为空字符串,符串的长度为0,data为NULL。


ngx_str_set(str, text)


设置字符串str为text,text必须为常量字符串。


ngx_str_null(str)


设置字符串str为空串,长度为0,data为NULL。


上面这四个函数,使用时一定要小心,ngx_string与ngx_null_string只能用于赋值时初始化,如:


ngx_str_t str = ngx_string("hello world");

ngx_str_t str1 = ngx_null_string();


ngx_str_t str, str1;

ngx_str_set(str, "hello world");

ngx_str_null(str);

不过要注意的是,ngx_string与ngx_str_set在调用时,传进去的字符串一定是常量字符串,否则会得到意想不到的错误。


void ngx_strlow(u_char *dst, u_char *src, size_t n);

将src的前n个字符转换成小写存放在dst字符串当中,调用者需要保证dst指向的空间大于等于n。操作不会对原字符串产生变动。如要更改原字符串,可以:

ngx_str_t str = ngx_string("hello world"); ngx_strlow(str->data, str->data, str->len);


ngx_strncmp(s1, s2, n)

不区分大小写的字符串比较,只比较前n个字符。

ngx_strcmp(s1, s2)

不区分大小写的不带长度的字符串比较。

ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);

区分大小写的不带长度的字符串比较。

ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);

区分大小写的带长度的字符串比较,只比较前n个字符。


u_char * ngx_cdecl ngx_sprintf(u_char *buf, const char *fmt, ...);

u_char * ngx_cdecl ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);

u_char * ngx_cdecl ngx_slprintf(u_char *buf, u_char *last, const char *fmt, ...);

上面这三个函数用于字符串格式化,ngx_snprintf的第二个参数max指明buf的空间大小,ngx_slprintf则通过last来指明buf空间的大小。推荐使用第二个或第三个函数来格式化字符串,ngx_sprintf函数还是比较危险的,容易产生缓冲区溢出漏洞。


ngx_pool_t

void *ngx_palloc(ngx_pool_t *pool, size_t size);

从这个pool中分配一块为size大小的内存。注意,此函数分配的内存的起始地址按照NGX_ALIGNMENT进行了对齐。对齐操作会提高系统处理的速度,但会造成少量内存的浪费。


void *ngx_pnalloc(ngx_pool_t *pool, size_t size);

从这个pool中分配一块为size大小的内存。但是此函数分配的内存并没有像上面的函数那样进行过对齐。


void *ngx_pcalloc(ngx_pool_t *pool, size_t size);

该函数也是分配size大小的内存,并且对分配的内存块进行了清零。内部实际上是转调用ngx_palloc实现的。


void *ngx_prealloc(ngx_pool_t *pool, void *p, size_t old_size, size_t new_size);

对指针p指向的一块内存再分配。如果p是NULL,则直接分配一块新的new_size大小的内存。

如果p不是NULL, 新分配一块内存,并把旧内存中的内容拷贝至新内存块中,然后释放p的旧内存(具体能不能释放旧的,要视具体的情况而定,这里不再详述)。


ngx_array_t

typedef struct ngx_array_s       ngx_array_t;
struct ngx_array_s {
    void        *elts;
    ngx_uint_t   nelts;
    size_t       size;
    ngx_uint_t   nalloc;
    ngx_pool_t  *pool;
};

elts:指向实际的数据存储区域。

nelts:数组实际元素个数。

size:数组单个元素的大小,单位是字节。

nalloc:数组的容量。表示该数组在不引发扩容的前提下,可以最多存储的元素的个数。当nelts增长到达nalloc 时,如果再往此数组中存储元素,则会引发数组的扩容。数组的容量将会扩展到原有容量的2倍大小。实际上是分配新的一块内存,新的一块内存的大小是原有内存大小的2倍。原有的数据会被拷贝到新的一块内存中。

pool:该数组用来分配内存的内存池。


ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);

创建一个新的数组对象,并返回这个对象。

p:数组分配内存使用的内存池;

n:数组的初始容量大小,即可以在不扩容的情况下最多可以容纳的元素个数。

size:单个元素的大小,单位是字节。


void ngx_array_destroy(ngx_array_t *a);

销毁该数组对象,并释放其对应的内存给对应的内存池。需要注意的是,调用该函数以后,数组对象上个字段的值并没有被清零。所以即便这个时候对象a上各字段还有有意义的值,但是这个对象绝对不应该被再使用了,除非是使用ngx_array_init函数。


void *ngx_array_push(ngx_array_t *a);

在数组a上新追加一个元素,并返回指向新元素的指针。需要把返回的指针使用类型转换,转换为具体的类型,然后再给新元素本身或者是各字段(如果数组的元素是复杂类型)赋值。


void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);

在数组a上追加n个元素,并返回指向这些追加元素的首个元素的位置的指针。


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

如果一个数组对象是被分配在堆上的,那么当调用ngx_array_destroy销毁以后,如果想再次使用,就可以调用此函数。

如果一个数组对象是被分配在栈上的,那么就需要调用此函数,进行初始化的工作以后,才可以使用。

注意事项: 数组在扩容时,旧的内存不会被释放,会造成内存的浪费。因此,最好能提前规划好数组的容量,在创建或者初始化的时候一次搞定,避免多次扩容,造成内存浪费。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值