c - Linux内核分配实现中的指针计算

标签 c linux pointers caching

来自指南Understanding The Linux Kernel, 3rd Edition , 8.2.12 章。分配一个Slab对象,有如下一段代码:

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] 行:

Because the local cache array is stored right after the ac descriptor, ((void**)(ac+1))[--ac->avail] gets the address of that free object and decreases the value of ac->avail.

但是,由于 ac 是指向类型 struct array_cache 的指针,它包含以下字段(按此顺序)-

[type] unsigned int

[name] avail

[description] Number of pointers to available objects in the local cache. The field also acts as the index of the first free slot in the cache.

[type] unsigned int

[name] limit

[description] Size of the local cache that is, the maximum number of pointers in the local cache.

[type] unsigned int

[name] batch_count

[description] Chunk size for local cache refill or emptying.

[type] unsigned int

[name] touched

[description] Flag set to 1 if the local cache has been recently used.

所以 ac+1 将指向 avail 值的第二个字节(或相反的 Endian 情况下的第 3 个字节),这根本没有意义。

我是不是理解错了?

最佳答案

是的,你错了。

指针运算是根据所指向的类型,而不是字节。

考虑一下:

int a[2], *p = a;

++p;

这使得 p 等于 &a[1],而不是 ((char *) &a[0]) + 1。因此,该增量会将实际指针值增加 sizeof *p,即 sizeof (int)

请记住,数组索引是通过指针算法工作的,因此出于这个原因也必须采用这种方式。

在 C 中实现各种数据结构时,您有一 block 内存以某个 struct 的实例开始,然后是其他数据(通常由 中的字段描述)是很常见的>结构)。该数据的第一个字节位于 sp + 1,假设 sp 是指向 struct 的指针,就像您显示的代码一样。

关于c - Linux内核分配实现中的指针计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46846480/

相关文章:

c - C中的面向对象编程

linux - 如何安装升级到新版本的 awstats Linux/UNIX *.tar.gz tarball 文件

c++ - OpenCV cv::Mat to short*(避免 memcpy)

c - 是否可以覆盖目标模块(gcc、ld、x86、objcopy)中的静态函数?

C - 指针和数组

c - 在 C 中使用清理处理程序安全取消 pthread

linux - 如何从远程机器获取文件夹到本地机器?

pointers - 在 C 中将指针复制到指针 'contents'

c - 初始化中结构内存分配中的指针(c99)

java - 修改当前实例的副本会影响当前实例吗? ( java )