指针的本质--u_char*指针在Nginx源码中的应用及原因
GNU下的void *p++相當(dāng)于char *p++ 也就是移動(dòng)一個(gè)字節(jié)。
下面的代碼是Nginx中內(nèi)存池的結(jié)構(gòu)體代碼,其中l(wèi)ast和end是表示內(nèi)存地址的。
last是u_char*指針類型也就是unsigned char
typedef struct {u_char *last;u_char *end;ngx_pool_t *next;ngx_uint_t failed;
} ngx_pool_data_t;
?
由于unsigned char*指針表示一個(gè)字節(jié) 所以是0-255之間
257已經(jīng)需要2個(gè)字節(jié)10000001,所以如果用unsigned char*類型來聲明該段地址(&k),那么多出的部分會(huì)被舍去,所以如果對(duì)其解引用就是00000001,而不是257
本來,指針變量不管是什么類型其實(shí)都完整的存儲(chǔ)了“地址”,但是不同類型解引用就會(huì)產(chǎn)生對(duì)應(yīng)的值!
nginx移動(dòng)last指針,分配內(nèi)存的函數(shù)
void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{u_char *m;ngx_pool_t *p;if (size <= pool->max) {p = pool->current;do {m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);if ((size_t) (p->d.end - m) >= size) {p->d.last = m + size;return m;}p = p->d.next;} while (p);return ngx_palloc_block(pool, size);}return ngx_palloc_large(pool, size);
}
聲明了一個(gè)u_char*m的變量,然后返回給空指針。其實(shí),聲明last為空指針也可以,那樣要如這里:
指針的本質(zhì)-void和void*指針在nginx中的應(yīng)用
感覺自己2篇文章其實(shí)還是在說指針,講同一個(gè)東西。
如果需要增加內(nèi)存
static void *
ngx_palloc_block(ngx_pool_t *pool, size_t size)
{u_char *m;size_t psize;ngx_pool_t *p, *new, *current;psize = (size_t) (pool->d.end - (u_char *) pool);m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);if (m == NULL) {return NULL;}new = (ngx_pool_t *) m;new->d.end = m + psize;new->d.next = NULL;new->d.failed = 0;m += sizeof(ngx_pool_data_t);m = ngx_align_ptr(m, NGX_ALIGNMENT);new->d.last = m + size;current = pool->current;for (p = current; p->d.next; p = p->d.next) {if (p->d.failed++ > 4) {current = p->d.next;}}p->d.next = new;pool->current = current ? current : new;return m;
}先是聲明一個(gè)u_char????? *m; 后面給其分配內(nèi)存。
然后是講*m轉(zhuǎn)化為ngx_pool_t?? *new= (ngx_pool_t *) m;
然后把new串到p上,p也就是前面已經(jīng)分配了的內(nèi)存池(由于空間不夠需要擴(kuò)容)
最后,返回m。最關(guān)鍵就是m? 注意:m和new后來就完全不一樣了,因?yàn)閙是last指針,也就是新分配的內(nèi)存地址!
對(duì)于調(diào)用ngx_palloc()函數(shù)的變量來說,由于ngx_palloc()返回的是void*指針,所以可以給任意其他類型指針!
總結(jié):
因?yàn)閡_char*和char*指針都是指向1個(gè)字節(jié)的地址,所以用u_char*和char*指針進(jìn)行位移運(yùn)算是非常方便的!這也是為什么nginx用u_char*做last指針類型的原因
設(shè)想如果用的是Int*,那么last+1實(shí)際上就是+4個(gè)字節(jié),非常不方便。
其實(shí)用void*也可以定義last指針的,但是這樣需要做一次轉(zhuǎn)換在運(yùn)算的時(shí)候!
所謂內(nèi)存池,就是劃一塊內(nèi)存,從內(nèi)存池中申請(qǐng)就是返回一個(gè)地址,和malloc一樣本質(zhì)都是返回一個(gè)地址,準(zhǔn)確的說是void*!
總結(jié)
以上是生活随笔為你收集整理的指针的本质--u_char*指针在Nginx源码中的应用及原因的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx模块开发
- 下一篇: linux环境insight安装与使用