简体   繁体   中英

How to dereference a n-levels void pointer to an int pointer

I'm trying to implement the following function:

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

Where p is actually a n-levels pointer to an int value and the function must 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

And so on...

So, I think that the following implementation may 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 assume that size of a pointer always equals a size of an int, and I know it is not true. However, since p is always a pointer to pointer to int ( n times), I think that maybe I can always cast p to pointer to int as I do in the code.

Is my idea correct? I cannot found any problem similar to this on internet.

Thanks in advance!

Your bottom case of the recursion is not correct, since this supposes that void* and int have the same width.

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

Would be better.

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

Anyway, a pointer to something is the same size as a pointer to a pointer to something, etc.

So you can cast a (void*) to a (void**).

But casting a pointer to an int may loose information, because 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);
}

this assumes that your int is no bigger than a 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 that assumption for everything except the n=0 case:

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);
}

In C you can replace the static_cast<X> and reinterpret_cast<X> clauses with (X) .

In general it's usually better to stick with iterative solution, rather than recursive, if it's possible.

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

IDEONE: demo

It lets you avoid problems with theoretiaclly possible stack overflow for large n s (I have no idea why would you need to dereference 1000+ levels deep pointer, but I have no idea why you need this function in the first place, so let's keep the function safe) and avoids unnecessary function call overhead (yes, it might get optimized by the compiler, but why not write it optimally in the first place?).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM