简体   繁体   English

当一个指针作为指向另一个函数内部的指针的指针传递时会发生什么?

[英]what happens when a pointer is passed as a pointer to a pointer inside another function?

So can someone explain what would happen if I pass ...*p as the argument name for the foo function那么有人可以解释如果我将 ...*p 作为 foo 函数的参数名称会发生​​什么

int main()

{

    int i = 10;
    int *const p = &i;
    foo(&p);
    printf("%d\n", *p);

}

void foo(int **p)

{
    int j = 11;
    *p = &j;
    printf("%d\n", **p);

}

Don't do that.不要那样做。 You'll have a pointer to an undefined memory location on the stack.您将有一个指向堆栈上未定义内存位置的指针。 Any other function call between foo(&p); foo(&p);之间的任何其他函数调用and printf("%d\\n", *p);printf("%d\\n", *p); is bound to overwrite that memory location with new data.必然会用新数据覆盖该内存位置。

Let's look at a simple example here!让我们看一个简单的例子! We have a function print_address , which takes an address and prints it.我们有一个函数print_address ,它接受一个地址并打印它。 We're gonna print the address of an int, as well as the address of a pointer to that int, and a pointer of a pointer to that int.我们将打印一个 int 的地址,以及一个指向该 int 的指针的地址,以及一个指向该 int 的指针的指针。

#include <stdio.h>

void print_address(void* addr) {
    printf("Address: %p\n", addr); 
}
int main()
{
    int value = 0;
    int* value_ptr = &value;
    int** value_ptr_ptr = &value_ptr; 

    print_address(&value);
    print_address(&value_ptr);
    print_address(&value_ptr_ptr); 

    return 0;
}

When I run this code, I get the following output:当我运行此代码时,我得到以下输出:

Address: 0x7fffa4936fec                                                                                                                                      
Address: 0x7fffa4936ff0                                                                                                                                      
Address: 0x7fffa4936ff8  

The first address is to value , the second address is to value_ptr , and the third address is to value_ptr_ptr .第一个地址是value ,第二个地址是value_ptr ,第三个地址是value_ptr_ptr Each address is a little higher than the previous one, because each variable has been stored a little higher up on the stack.每个地址都比前一个地址高一点,因为每个变量都存储在堆栈的更高位置。

The same thing happens with function calls.函数调用也会发生同样的事情。 When we call a function, the memory for all the local variables in that function is stored a little higher up on the stack then the memory for all the local variables in the current function:当我们调用一个函数时,该函数中所有局部变量的内存存储在堆栈上比当前函数中所有局部变量的内存高一点:

#include <stdio.h>

void print_address(void* addr) {
    printf("Address: %p\n", addr); 
}

void f3(int*** ptr) {
    print_address(ptr); 
}
void f2(int** ptr) {
    print_address(ptr);
    f3(&ptr);
}
void f1(int* ptr) {
    print_address(ptr); 
    f2(&ptr); 
}
int main()
{
    int value = 0;
    f1(&value); 

    return 0;
}

This time when I ran it, the output was这次当我运行它时,输出是

Address: 0x7ffeca71dc2c                                                                                                                                      
Address: 0x7ffeca71dc08                                                                                                                                      
Address: 0x7ffeca71dbe8  

If you notice, the gaps between addresses are higher, but that's because of the extra stack space it takes to do a function call.如果您注意到,地址之间的差距更大,但这是因为执行函数调用需要额外的堆栈空间。

j is destoyed after exiting foo , so doing anything with it after foo calling in main is incorrect, until you reset it on another object (I mean printf("%d\\n", *p) ). j在退出foo后被销毁,因此在foo调用main之后对其进行任何操作都是不正确的,直到您在另一个对象上重置它(我的意思是printf("%d\\n", *p) )。

Well, what you're doing is passing pointer on pointer on integer.好吧,你正在做的是在整数指针上传递指针。

As you could see, pointers are often used to pass arrays:如您所见,指针通常用于传递数组:

void print_array(int* a, int n) {
    for (int i = 0; i < n; i++)
        printf("%d ", a[i]);
    printf("\n");
}

And pointers on pointers are used to pass two-dimensional arrays, for example in int main(int argc, char** argv) { ... } argv is array of strings or array of arrays of char -s.指针上的指针用于传递二维数组,例如在int main(int argc, char** argv) { ... } argv是字符串数组或char -s 数组的数组。

You can't pass *p, but let's say you could...你不能通过 *p,但假设你可以......

It looks like you are trying to get your function to update a parent variable - and passing &p is the correct way to do it.看起来您正在尝试让您的函数更新父变量 - 传递 &p 是正确的方法。 But you are adding one too many dereference.但是您添加了太多的取消引用。 I highly recommend you read this: https://boredzo.org/pointers/我强烈建议您阅读此内容: https : //boredzo.org/pointers/

// Let's assume you only have 4 memory locations for variables: 1 2 3 and 4.
// let's call these m[1] m[2] m[3] and m[4]
// i is at 1, p is at 2, j is at 3, and the p inside the function is at 4.
// let's call that second p, q rather
// so you have: m[1..4] = { i, p, j, q }
// now execute the code in your head:

int main()

{

    int i = 10;          // m[1] = 10        
    int *const p = &i;   // m[2] = 1
    foo(&p);             // foo(2)
    printf("%d\n", *p);  // printf m[2]

}

void foo(int **q)        // q = m[m[2]] = m[1] = 10

{
    int j = 11;          // m[3] = 11
    *q = &j;             // m[10] = 3  // segfault!
    printf("%d\n", **q); // printf m[m[10]] = m[3] = 11 // if it didnt' segfault

}

It looks like this is what you are trying to do:看起来这就是您要执行的操作:

#include <stdio.h>

void b(int *q,int n) {
    *q=n;
}

int main() {
 int i=123; 
 int *p=&i; // *p and i are now synonymous

 printf("%i ",i);  
 printf("%i ",*p); // same thing 
 b(p,111);
 printf("%i ",i);
 b(&i,111);a       // same thing
 printf("%i ",i);
}

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

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