0

I have a block of memory void* block = calloc(1,100); and I want an array of pointers like this void* ptrs[]; but located in my memory block. I get confused for the "get function" since array of pointers is void** but block is void*

void* block = calloc(1,100);
void* getPtr(int i)
{
   return (?)(unsigned char*)block + i * __CHAR_BIT__))
}
void setPtr(int i, void* ptr)
{
   getPtr(i) = ptr;
}

//this seems to work now, but I have to return a reference to the pointer otherwise I cannot change is which seems strange since its a pointer
void*& getPtr(int i)
{
    return *(void **)((unsigned char*)block + i * __CHAR_BIT__);
}

void setPtr(int i, void* ptr)
{
    getPtr(i) = ptr;
}
3
  • a void* can point anywhere, for example to a void* Commented Aug 21, 2020 at 12:32
  • 1
    just out of curiosity, why not just std::vector<void*>? Commented Aug 21, 2020 at 13:43
  • @DavidHaim vector will allocate on some random address, not in my block Commented Aug 21, 2020 at 14:09

1 Answer 1

1

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*));
}
Sign up to request clarification or add additional context in comments.

1 Comment

Great answer, if you add a version of getPtr that returns the actual pointer not its address it will be excellent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.