GNU下的void *p++相当于char *p++ 也就是移动一个字节。
下面的代码是Nginx中内存池的结构体代码,其中last和end是表示内存地址的。
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*指针表示一个字节 所以是0-255之间
257已经需要2个字节10000001,所以如果用unsigned char*类型来声明该段地址(&k),那么多出的部分会被舍去,所以如果对其解引用就是00000001,而不是257
本来,指针变量不管是什么类型其实都完整的存储了“地址”,但是不同类型解引用就会产生对应的值!
nginx移动last指针,分配内存的函数
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);
}
声明了一个u_char*m的变量,然后返回给空指针。其实,声明last为空指针也可以,那样要如这里:
指针的本质-void和void*指针在nginx中的应用
感觉自己2篇文章其实还是在说指针,讲同一个东西。
如果需要增加内存
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;
}先是声明一个u_char *m; 后面给其分配内存。
然后是讲*m转化为ngx_pool_t *new= (ngx_pool_t *) m;
然后把new串到p上,p也就是前面已经分配了的内存池(由于空间不够需要扩容)
最后,返回m。最关键就是m 注意:m和new后来就完全不一样了,因为m是last指针,也就是新分配的内存地址!
对于调用ngx_palloc()函数的变量来说,由于ngx_palloc()返回的是void*指针,所以可以给任意其他类型指针!
总结:
因为u_char*和char*指针都是指向1个字节的地址,所以用u_char*和char*指针进行位移运算是非常方便的!这也是为什么nginx用u_char*做last指针类型的原因
设想如果用的是Int*,那么last+1实际上就是+4个字节,非常不方便。
其实用void*也可以定义last指针的,但是这样需要做一次转换在运算的时候!
所谓内存池,就是划一块内存,从内存池中申请就是返回一个地址,和malloc一样本质都是返回一个地址,准确的说是void*!

本文探讨了Nginx内存池中使用u_char*指针的原因,分析了其作为字节地址的优势,以及在内存管理中的移动和转换操作。通过示例展示了指针类型对内存分配的影响,强调了u_char*在位移运算中的便捷性,对比了与其他类型指针的区别。
643





