简体   繁体   中英

C Pointer to Pointer and Pass by Reference

I'm trying to learn C, and I'm hung up a bit on Pointers to Pointers. I think I understand why you need them, but can't quite get my head wrapped around what is happening.

For instance, the following code doesn't seem to work as I would expect it to:

#include <stdio.h>

int newp(char **p) {
  char d = 'b';
  *p = &d;
  /*printf("**p = %c\n", **p);*/
  return 1;
}

int main() {
  char c = 'a';
  char *p = &c;
  int result;

  result = newp(&p);
  printf("result = %d\n", result);
  printf("*p = %c\n", *p);
  printf("c = %c\n", c);

  return 0;
}

The result I get is this:

result = 1
*p = 
c = a

*p prints as nothing. Instead, I would expect *p = b .

However , if I uncomment line 6 (the printf in the newp function), then I get this:

**p = b
result = 1
*p = b
c = a

What am I missing?

You are dealing with undefined behaviour. The variable d is local (resides on the stack) and is not available after the enclosing function ( newp ) returns.

When dereferencing p outside newp , the address on the stack &d may be overwritten by some other local variable or it may contain garbage.

You are storing the address of a local variable ( d ) in *p and then dereferencing it when the variable has gone out of scope. Undefined Behavior

You might be "missing" the keyword static , as in:

int newp(char **p) {
    static char d = 'b';   /* <--- HERE */
    *p = &d;
    /*printf("**p = %c\n", **p);*/
    return 1;
}

This static keyword causes the compiler to locate the local variable in "static storage," which continues to exist (ie maintains its value) during the time periods after newp() has been called. However, there is only one copy of this memory -- each subsequent invocation of the containing function ( newp ) re-uses the same memory location and may overwrite the value at that time.

Without the static keyword to qualify your local variable declaration, the storage will be "automatic", which means that it is automatically discharged from current use after the containing function has returned. After newp returns, the memory formerly used for the local variable can be reused for any purpose.

#include <stdio.h>

// Here *pointer means that the parameter that this function 
// will expect will be a pointer. 
void changeViaPointer(int *pointer);

// Pointer of a pointer.
void changeViaPointerInBetween(int **pointer);

int main(){

    int number;
    number = 20;

    // Here *pointer means that the variable that is declared will be a pointer.
    int *pointer;

    // Actually asigning value to the pointer variable.
    pointer = &number;

    // Pointer of a pointer.
    int **pointerInBetween;

    // Assigning value to the pointer of a pointer. 
    // Assigning the memory location where this pointer points to. 
    // So this is a pointer in between.
    pointerInBetween = &pointer;

    printf("The number before changing is %d\n", number);

    // Pass the pointer variable.
    changeViaPointer(pointer);
    printf("The number after pointer changing is %d\n", number);

    // Pass the pointer of a pointer variable.
    changeViaPointerInBetween(pointerInBetween);
    printf("The number after pointer in between changing is %d\n", number);

    return 0;
}

void changeViaPointer(int *pointer){

    // Okay, at this point we have received a variable called pointer,
    // which points to some value. In order to access this value
    // we need to use *pointer.
    // BUT THIS IS DIFFERENT FROM THE *pointer IN THE FUNCTION DECLARATION!!!
    *pointer = *pointer + 20;
}

void changeViaPointerInBetween(int **pointer){

    // **pointer explanation:
    // Only pointer is the memory location
    // *pointer  is the value of that memory location, which in this specific case is also a memory location
    // **pointer is the value of what the other pointer points to.
    **pointer = **pointer + 20;
}

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