If you want to store pointers in your block, each of the elements will use sizeof(void *) bytes. Thus to get i-th pointer's location you'll need:
void* getPtr(int i)
{
return (unsigned char*)block + i * sizeof(void*);
}
Say, if block's address was 1, and pointer's size was 8, the 1st pointer would be written in the 8 bytes starting from address 1, the 2nd from address 9, etc.
get_ptr(1) returning void *, will just return some temp variable, in which 9 is written, if you assign to it, nothing will happen in the actual block. It won't return the actual pointer written in address 9.
And we can set like this:
void setPtr(int i, void* ptr)
{
memcpy(getPtr(i),&ptr, sizeof(void*));
}
Notice the &ptr. We do not want to write the value of the pointer, but rather the pointer itself, which is written in &ptr
In you second working option you are dereferencing the pointer pointing to the underlying pointer, thus returning the actual pointer, not its location. If getting back to our example, youa re no longer returning 9, but what is written in the address 9. And as you want to modify it in the block and not in the temp variable returned by the function, you need to return by reference.
UPDATE: Alternatively if you want a getPtr version returning the actual pointer as void*, you can use this:
void * getPtrLocation(int i)
{
return (unsigned char*)block + i * sizeof(void*);
}
void* getPtr(int i)
{
uintptr_t* r_ptr = (uintptr_t*)getPtrLocation(i);
// *r_ptr will return the actual address we have written
return reinterpret_cast<void*>(*r_ptr);
}
void setPtr(int i, void* ptr)
{
void * w_ptr = getPtrLocation(i);
memcpy(w_ptr,&ptr, sizeof(void*));
}
void*can point anywhere, for example to avoid*std::vector<void*>?