简体   繁体   中英

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

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); and 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. 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.

#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 . 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) ).

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.

You can't pass *p, but let's say you could...

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. But you are adding one too many dereference. I highly recommend you read this: 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);
}

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