How to dereference void n-levels pointer to int pointer

I am trying to implement the following function:

int foo(const void *p, unsigned int n);

      

Where p is actually an n-level pointer to an int value, and the function should return that value. So:

  • n = 0: value = (int)(p);

  • n = 1: value = *(int*)(p);

  • n = 2: p is a pointer to a pointer to an int value

Etc...

So, I think the following implementation might be correct:

int foo(const void *p, unsigned int n) {

    if (!n) {

        return (int)p;
    }

    return foo((void*)*((int*)p), n - 1);
}

      

But in this code, I am assuming that the pointer size is always the size of an int, and I know this is not correct. However, since p is always a pointer to a pointer to int (n times), I think that perhaps I can always distinguish p from a pointer to int, just like in the code.

Is my idea correct? I can't find any problems like this on the internet.

Thanks in advance!

+3


source to share


4 answers


Your recursion lowercase is incorrect, as it assumes void*

both int

are the same width.

if (n == 1) return *(int*)p;

      



Would be better.

+4


source


I'm not sure what you are trying to accomplish, but I suspect there is a better approach.

In any case, a pointer to something is the same size as a pointer to a pointer to something, etc.

So you can cast (void *) on (void **).



But casting a pointer to int may lose information, because there sizeof(void*)

may be> sizeof(int)

.

You should write:

int foo(const void *p, unsigned int n) {

    //if n is 0, then p is already an int, but has been casted to a void*
    //This should probably never happend, so you should assert that n > 0

    //if n is 1, then p is actually a pointer to an int
    if (n == 1) return *(int*)p; 

    //else dereference it (by casting it to a (void**) and *then* dereferencing it)
    return foo(*(void**)p, n-1);
}

      

+2


source


this assumes yours is int

nothing more than void*

:

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }

  return foo(*static_cast<void**>(p), n - 1);
}

      

we can avoid this assumption for everything except the case n=0

:

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }
  if (n==1) {
    return *static_cast<int*>(p);
  }

  return foo(*static_cast<void**>(p), n - 1);
}

      

As C

you can replace the proposals static_cast<X>

and reinterpret_cast<X>

on (X)

.

+2


source


In general, it is usually best to stick with an iterative solution rather than a recursive one if possible.

int foo(void *p, unsigned int n) {
    for (unsigned int i = 0; i < n; ++i) {
        p = *((void**)p);
    }
    return (int)p;
}

      

IDEONE: demo

This allows you to avoid problems with theoretically possible stack overflows for large ones n

(I have no idea why you need to look for a level pointer over 1000 levels, but I don't know why you need this function in the first place, so keep the function safe) and avoids unnecessary function calls (yes, it can be optimized by the compiler, but why not write it optimally in the first place?).

+1


source







All Articles