简体   繁体   English

将“指针指向指针”和“指针地址”传递给函数之间的区别

[英]Difference between passing “pointer to pointer” and “address of pointer” to a function

I have a function that takes a char ** ; 我有一个带char **的函数; it uses it internally for maintaining context between successive calls. 它在内部使用它来维护连续调用之间的上下文。

What is the difference between defining char **x and passing x to it, and defining char *x and passing &x ? 定义char **x并将x传递给它,与定义char *x并传递&x什么区别?


For context: I tried to implement the example at strtok man page on my own before reading the source code. 对于上下文:在阅读源代码之前,我尝试自己在strtok手册页上实现示例。 And I got segfaults. 而且我遇到了段错误。 Then after attempts I looked at the source. 然后经过尝试,我查看了源代码。

The problem was that I defined char **x and passed x as the **saveptr argument, but changing the definition to char *x and the passing to &x solved the problem. 问题是我定义了char **x并将x作为**saveptr参数传递,但是将定义更改为char *x并传递给&x解决了问题。

What is the problem exactly? 到底是什么问题?

The first version, with char **x; 第一个版本,带有char **x; and passing x , creates and uses an uninitialised pointer to pointer to char. 并传递x ,创建并使用未初始化的指向char的指针。
The second version, with char * x; 第二个版本,带有char * x; and passing &x , creates an uninitialised pointer to char, but passes a value which is a valid address of a pointer to char, and is a defined value (ie like an initialised pointer to uninitialised pointer to char). 并传递&x ,创建指向char的未初始化指针,但是传递一个值,该值是指向char的指针的有效地址,并且是定义的值(即,类似于指向未初始化的指向char的指针的指针)。

Basically with first version you ask to write at a "random" place in memory (almost sure way to get a segfault); 基本上,对于第一个版本,您要求在内存中的“随机”位置进行写(这是获得段错误的几乎肯定的方法); with second, you ask to write into an existing pointer variable. 其次,您要求写入现有的指针变量。

When you define eg 当您定义例如

char **x;

Then you simply define a pointer. 然后,您只需定义一个指针。 It doesn't matter that it's a pointer to another pointer, the important part is that it's just a pointer. 它不是指向另一个指针的指针,重要的是它只是一个指针。 And as such, with the definition shown above, it's not initialized. 因此,使用上面显示的定义,它尚未初始化。 It doesn't point anywhere special. 它没有特别之处。 Dereferencing it, like you most likely do in the function, leads to undefined behavior . 像在函数中最有可能那样取消引用它会导致未定义的行为

On the other hand, with a definition like 另一方面,像

char *x;

and using &x to get a pointer to it, the pointer returned by &x points somewhere valid, to the variable x . 并使用&x指向它的指针, &x返回的指针指向有效的变量x Dereferencing &x will allow the function to access and modify x itself. 取消引用&x将允许该函数访问和修改x本身。

Using the address-of operator in this way is a way to emulate pass by reference , which C doesn't have. 以这种方式使用address-of运算符是一种模拟C所没有的按引用传递的方式。

Because all function arguments are passed by value in C, if you define char **x and pass x , it won't be modified by the function. 因为所有函数参数都 C中的值传递 ,所以如果您定义char **x并传递x ,则函数将不会对其进行修改。 If you define char *x and pass &x , it can be modified (change its pointing address). 如果定义char *x并传递&x ,则可以对其进行修改(更改其指向地址)。

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

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