I have an array of void*
s called bins
. Each void*
points to a chunk.
Each chunk consists of three things laid out one after the other in contiguous memory:
uint32_t
.void*
.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?
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