简体   繁体   English

如何取消引用指向int指针的n级void指针

[英]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. 其中p实际上是指向int值的n级指针,函数必须返回该值。 So: 所以:

  • n = 0 : value = (int)(p); n = 0value = (int)(p);
  • n = 1 : value = *(int*)(p); n = 1value = *(int*)(p);
  • n = 2 : p is a pointer to a pointer to an int value n = 2 :p是指向int值的指针

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. 但是,在这段代码中,我假设指针的大小总是等于int的大小,我知道它不是真的。 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. 但是,由于p总是一个指向int( n次)指针的指针,我想也许我总是像在代码中那样将p转换为指向int的指针。

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. 递归的底部情况不正确,因为这假设void*int具有相同的宽度。

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**). 所以你可以将(void *)转换为(void **)。

But casting a pointer to an int may loose information, because sizeof(void*) may be > sizeof(int) . 但是,将指针强制转换为int可能会丢失信息,因为sizeof(void*)可能是> 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不大于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: 除了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);
}

In C you can replace the static_cast<X> and reinterpret_cast<X> clauses with (X) . C您可以使用(X)替换static_cast<X>reinterpret_cast<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 IDEONE: 演示

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?). 它可以让你避免与大theoretiaclly可能的堆栈溢出问题n秒(我不知道为什么你会需要提领1000+层次深的指针,但我不知道为什么你需要摆在首位这一功能,所以让我们保持函数安全)并避免不必要的函数调用开销(是的,它可能会被编译器优化,但为什么不首先以最佳方式编写它?)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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