Search code examples
cpointersdereference

How can I dereference a void* in C?


I have an array of void*s called bins. Each void* points to a chunk.

Chunks

Each chunk consists of three things laid out one after the other in contiguous memory:

  1. The size in bytes of the chunk. This is represented by a uint32_t.
  2. The address of the next valid chunk. This is represented by a void*.
  3. The data of the chunk. For all intents and purposes this is garbage and can be ignored.

What I Want to Do

My algorithm works like this:

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

I'm having a lot of trouble with getting the address of the next chunk. Right now, my implementation works, but it is very hacky:

void* next = (void*)*(uint64_t*)(bin[index] + sizeof(uint32_t));

The main issue is casting the address bin[index] + sizeof(uint32_t) to a uint64_t before dereferencing it. Is there any way to just dereference this as if it were an address, or a pointer?


Solution

  • You could define a structure with 2 members and cast the pointer:

    struct chunk_head {
        uint32_t size;
        void *next;
    };
    
    void *next = ((struct chunk_head*)bins[index])->next;
    

    This assumes void* is aligned on 32 bits.

    A more direct but less readable way is this:

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

    Your approach is non portable as it relies on void* arithmetic which is a gcc extension. Standard C does not allow adding a number to a void*. Note also that you read a pointer to uint32_t and cast that to a void*, which is not exactly the same as casting the address as a void** and dereferencing it to read the void* pointer:

    void *next = *(void**)(bin[index] + sizeof(uint32_t));  // gcc extension