如何在C中取消引用void *?

时间:2016-02-28 22:39:32

标签: c pointers dereference

我有一个名为void*的{​​{1}}数组。每个bins指向

结块

每个块由三个在连续记忆中依次布置的东西组成:

  1. 块的字节大小。这由void*
  2. 表示
  3. 下一个有效块的地址。这由uint32_t
  4. 表示
  5. 块的数据。对于所有意图和目的,这是垃圾,可以忽略。
  6. 我想做什么

    我的算法是这样的:

    void*

    我在获取下一个块的地址时遇到了很多麻烦。现在,我的实现工作正常,但非常 hacky:

    if bins[index] == NULL: foo()
    otherwise:
        save the address of this chunk (it is bins[index])
        get the address of the next chunk
        set bins[index] to the address of the next chunk
        return the original value bins[index] that we saved
    

    主要问题是在解除引用之前将地址void* next = (void*)*(uint64_t*)(bin[index] + sizeof(uint32_t)); 转换为bin[index] + sizeof(uint32_t)。有没有办法只是取消引用它,就好像它是一个地址或一个指针?

1 个答案:

答案 0 :(得分:1)

您可以定义一个包含2个成员的结构并投射指针:

struct chunk_head {
    uint32_t size;
    void *next;
};

void *next = ((struct chunk_head*)bins[index])->next;

这假设void*在32位上对齐。

这是一个更直接但不太可读的方式:

void *next = *(void**)((uint64_t*)bins[index] + 1);

您的方法不可移植,因为它依赖于void*算术,这是一个gcc扩展。标准C不允许向void*添加数字。另请注意,您已阅读指向uint32_t的指针并将其强制转换为void*,这与将地址转换为void**并将其解除引用以读取{{1}不完全相同指针:

void*