简体   繁体   English

将空赋给双指针

[英]Assigning void to double pointer

I need to understand why assigning void* to int** will work, but when printing the value of int** , it will not work. 我需要理解为什么将void*分配给int**会起作用,但是当打印int**的值时,它将不起作用。 Here's the code: 这是代码:

int k = 3;
int *l = &k;
void *a = l; 
int **c = a; // if I assign, &a, the below line work, but get warning: incompatible
             // pointer type.
printf("%d", **c); // Code break;

But this line 但是这条线

printf("%d", *c); // will work, but get warning "%d expect int but of type int *".

Update: I saw this type of code in OOC book where author do this: 更新:我在OOC book看到了这种类型的代码,作者在其中进行以下操作:

struct Class {
   size_t size;
   int (*differ)(const void *self, const void *b);
   ..... Some more code ....

};

int differ(const void *self, const void *b) {
  // Note this line
  const struct Class **cp = self;
  assert(self && *cp && (*cp)->differ);
  return (*cp)->differ(self, b);
}

You have this situation: 您有这种情况:

+---+
| l | --\
+---+    \     +---+
          >--> | k |
+---+    /     +---+
| a | --/
+---+

Ie both l and a points directly to k . l和直接指向k a点。

When you then do 那你什么时候做

int **c = a;

you make c point to what a is pointing to as well (ie it's the same as doing int **c = &k ), but you declare c to be a pointer to pointer to an int , but make it point directly to an int . 您也使c指向a所指向的内容(即,与做int **c = &k ),但是您声明c为指向int指针,但直接将其指向int That means using single dereference ( *c ) you get the value of k , and when you you use double dereference ( **c ) you use the value of k as a pointer (which it isn't). 这意味着使用单解引用( *c )可以得到k的值,而当您使用双解引用( **c )时可以使用k的值作为指针(不是)。

I assume what you really want is this situation: 我认为您真正想要的是这种情况:

+---+     +---+     +---+
| a | --> | l | --> | k |
+---+     +---+     +---+

which you will get by doing 你将通过做得到

void *a = &l;

Then using c as a pointer to pointer will work because then a is a pointer to a pointer. 然后将c用作指向指针的指针将起作用,因为a是指向指针的指针。


If you continue with the first scenario, where you have 如果继续第一种情况,

int   k;
int  *l = &k;
void *a = l;

and then do 然后做

int **c = (int **) &a;  // The typecast is needed

Then you have the following situation: 那么您将遇到以下情况:

+---+
          | l | --\
          +---+    \     +---+
                    >--> | k |
+---+     +---+    /     +---+
| c | --> | a | --/
+---+     +---+

This will work because then c really is a pointer to a pointer to something. 这将起作用,因为那时c实际上指向某物的指针。

This is why you have to be careful with void* pointers. 这就是为什么您必须小心使用void*指针的原因。 You can assign any pointer to them, and you can assign them to any other pointer. 您可以为它们分配任何指针,也可以将它们分配给任何其他指针。 Even if it doesn't make sense (like your example). 即使这没有任何意义(例如您的示例)。

When you assign int **c = a , you've committed an error, that I think you're already aware of. 当您分配int **c = a ,您犯了一个错误,我想您已经知道了。 You've changed levels of indirection ( a came from an int* , but you're assigning it to an int** ), but didn't take another address-of ( & ). 您已经更改了间接级别( a来自int* ,但是您将其分配给int** ),但是没有采用其他地址( & )。

Your program fails for the same reason that, if you eliminated the void* a , and instead tried this, it would fail. 您的程序由于以下原因而失败:如果消除了void* a ,而是尝试了该操作,它将失败。

int k = 3;
int *l = &k;
int **c = l;    // Error - wrong level of indirection.

This is low-level C. Just because the compiler lets you do something doesn't mean it will work. 这是低级的C语言。仅仅因为编译器允许您执行某些操作,并不意味着它将起作用。

The solution to this question is: Don't do it . 这个问题的解决方案是: 不要这样做

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

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