Nginx資料結構及相關介面函式

2021-06-17 20:58:28 字數 3968 閱讀 9129

本文**

1. 字串ngx_str_t

typedef struct  ngx_str_t;

1.1介面函式

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函式還是比較危險的,容易產生緩衝區溢位漏洞。

2. 記憶體池結構ngx_pool_t

typedef struct ngx_pool_cleanup_s  ngx_pool_cleanup_t;

struct ngx_pool_cleanup_s ;

typedef struct ngx_pool_large_s  ngx_pool_large_t;

struct ngx_pool_large_s ;

typedef struct ngx_pool_data_t;

struct ngx_pool_s ;

2.1介面函式

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的舊記憶體(具體能不能釋放舊的,要視具體的情況而定,這裡不再詳述)。

3.陣列ngx_array_t

typedef struct ngx_array_s       ngx_array_t;

struct ngx_array_s ;

elts:指向實際的資料儲存區域。

nelts:陣列實際元素個數。

size:陣列單個元素的大小,單位是位元組。

nalloc:陣列的容量。表示該陣列在不引發擴容的前提下,可以最多儲存的元素的個數。當nelts增長到達nalloc 時,如果再往此陣列中儲存元素,則會引發陣列的擴容。陣列的容量將會擴充套件到原有容量的2倍大小。實際上是分配新的一塊記憶體,新的一塊記憶體的大小是原有記憶體大小的2倍。原有的資料會被拷貝到新的一塊記憶體中。

pool:該陣列用來分配記憶體的記憶體池。

3.1介面函式

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銷毀以後,如果想再次使用,就可以呼叫此函式。

如果乙個陣列物件是被分配在棧上的,那麼就需要呼叫此函式,進行初始化的工作以後,才可以使用。

注意事項: 陣列在擴容時,舊的記憶體不會被釋放,會造成記憶體的浪費。因此,最好能提前規劃好陣列的容量,在建立或者初始化的時候一次搞定,避免多次擴容,造成記憶體浪費。

資料結構 佇列及相關操作 重點

只允許在一端進行插入資料操作,在另一端進行刪除資料操作的特殊線性表,佇列具有先進先出 fifo first in first out 入佇列 進行插入操作的一端稱為隊尾 出佇列 進行刪除操作的一端稱為隊頭 佇列的假溢位 順序結構實現佇列,在刪除元素 出佇列 時,直接搬移元素,時間複雜度為o n 但是...

redis的資料結構及相關命令

redis 儲存的是 key,value 格式的資料,其中 key都是字串,value有5 種不同的資料結構 value 的資料結構 1 字串型別 string 2 雜湊型別hash map格式 3 列表型別 list linkedlist 格式。支援重複元素 4 集合型別 set 不允許重複元素 ...

nginx資料結構(ngx str t)

typedef struct ngx str t 通過乙個以 0 結尾的普通字串str構造乙個nginx的字串,鑑於其中採用sizeof操作符計算字串長度,因此引數必須是乙個常量字串。define ngx string str 使用ngx null string初始化字串為空字串 define ng...