C Linux内核分配实现中的指针计算
参考指南第8.2.12章。分配楼板对象时,有以下代码:C Linux内核分配实现中的指针计算,c,linux,pointers,caching,C,Linux,Pointers,Caching,参考指南第8.2.12章。分配楼板对象时,有以下代码: void * kmem_cache_alloc(kmem_cache_t *cachep, int flags) { unsigned long save_flags; void *objp; struct array_cache *ac; local_irq_save(save_flags); ac = cache_p->array[smp_processor_id()];
void * kmem_cache_alloc(kmem_cache_t *cachep, int flags)
{
unsigned long save_flags;
void *objp;
struct array_cache *ac;
local_irq_save(save_flags);
ac = cache_p->array[smp_processor_id()];
if (ac->avail)
{
ac->touched = 1;
objp = ((void**)(ac+1))[--ac->avail];
} else
objp = cache_alloc_refill(cachep, flags);
local_irq_restore(save_flags); return objp;
}
现在,根据指南,查看行((void**)(ac+1))[--ac->avail]
:
因为本地缓存阵列存储在ac描述符之后,
((void**)(ac+1))[--ac->avail]获取该自由对象的地址,并
降低ac->avail的值
但是,由于ac
是指向类型struct array\u cache
的指针,该类型包含以下字段(按此顺序)-
[type]无符号整数
[姓名]有效
[说明]指向本地缓存中可用对象的指针数。
该字段还充当缓存中第一个可用插槽的索引
[type]无符号整数
[姓名]限额
[说明]本地缓存的大小,即本地缓存中的最大指针数
[type]无符号整数
[名称]批次计数
[说明]本地缓存重新填充或清空的块大小
[type]无符号整数
[姓名]感动
[说明]如果最近使用了本地缓存,则标志设置为1
因此,ac+1
将指向avail
值的第二个字节(或相反端的第三个字节),这毫无意义
我弄错了吗?是的,你弄错了
指针算法是根据所指向的类型而不是字节来计算的
考虑这一点:
int a[2], *p = a;
++p;
这使得p
等于&a[1]
,而不是((char*)&a[0])+1
。因此,该增量将实际指针值增加sizeof*p
,即sizeof(int)
请记住,数组索引是通过指针算法工作的,因此也必须采用这种方式
在C语言中实现各种数据结构时,通常会有一个内存块,该内存块从某个
struct
的实例开始,然后是其他数据(通常由struct
中的字段描述)。该数据的第一个字节位于sp+1
,假设sp
是指向struct
的指针,就像您显示的代码一样。您能提供这种类型编码的更多常用用法和示例吗?我希望使用另一个结构来包装这个数据,这个包装结构将有一个指向另一个结构的指针字段,还有一个指向另一个数据的字段。这条路很干净。为什么要使用这样的代码?它有什么好处?