understand passing parameters by reference with dynamic allocation

前端 未结 5 2012
难免孤独
难免孤独 2021-01-25 16:59

I\'m trying understand how to pass a parameter by reference in C language. So I wrote this code to test the behavior of parameters passing:

#include 

        
相关标签:
5条回答
  • 2021-01-25 17:40

    The answer posted by nos is correct.

    Also note that the first of the two posted programs will actually crash on many systems, when the printf line in main() tries to dereference main's pointer n, which was never set:

       printf("%d.\n", *n);
    
    0 讨论(0)
  • 2021-01-25 17:48

    Actually not really much a difference, except the first one is broken. :) (Well, both are, but the first is broken more).

    Let me explain what happens in the second case:

    • variable n of type pointer-to-int is allocated on the stack
    • a new variable of type int is allocated to the stack, it's address is stored in variable n
    • function alocar is called, being passed the copy of variable n, which is the copy of the address of our variable of type int
    • the function sets the int variable being pointed by n to 12
    • the function prints the value of the variable being pointed by n (12)
    • the function returns

    The first case:

    • variable n of type pointer-to-int is allocated on the stack
    • the function alocar is called with a copy of the variable n (which is still uninitialized - contains an unknown value)
    • a new variable of type int is created in memory and the local copy of variable n in function alocar is set to point to that new variable
    • the variable (pointed by the function's local copy of n) is set to 12 and printed
    • the function returns, again in the main() function:
    • since the original n variable in main is still uninitialized, it points to a random place in memory. So the value in random place in memory is printed (which is likely to crash your program).

    Also, both programs are broken because they don't free the memory allocated by malloc().

    0 讨论(0)
  • 2021-01-25 17:50

    You want to modify the value of n in main, not what n points to, so you need to pass a pointer to it. Since the type of n in main is int *, the parameter to alocar needs to be of type int **:

    void alocar(int **n)
    {
      *n = malloc(sizeof **n); // note no cast, operand of sizeof
      if (!*n)
        exit(-1);
    
      **n = 12;
      printf("%d\n", **n);
    }
    
    int main(void)
    {
      int *n;
      alocar(&n);
      printf("%d\n", *n);  // we've already tested against n being NULL in alocar
      free(n);             // always clean up after yourself
      return 0;
    }
    
    0 讨论(0)
  • 2021-01-25 17:56

    See, what's happened in first program.

    Before call to alocar we have just variable n in main, pointing to some undefined place:

     main()::n [  X--]--->(?)
    

    (there's value in square brackets, which is undefined, marked as X). Then we call alocar, and we have another variable in alocar's scope, which have a copy of origianl var.

     main()::n   [  X--]--->(?)
     alocar()::n [  X--]-----^
    

    Now, allocate some memory:

     main()::n   [  X--]--->(?)
     alocar()::n [  *--]--->[   Y  ]
    

    Assign value to allocated var:

     main()::n   [  X--]--->(?)
     alocar()::n [  *--]--->[  12  ]
    

    Return. alocar()::n is removed as it live only while alocar() is executed.

     main()::n   [  X--]--->(?)
                            [  12  ]
    

    main()::n is still pointing to some undefined place... (Which possibly stores value 0) And no one points to allocated place.

    0 讨论(0)
  • 2021-01-25 17:58

    C is pass-by-value, it doesn't provide pass-by-reference. In your case, the pointer (not what it points to) is copied to the function paramer (the pointer is passed by value - the value of a pointer is an address)

    void alocar(int* n){
       //n is just a local variable here.
       n = (int*) malloc( sizeof(int));
      //assigning to n just assigns to the local
      //n variable, the caller is not affected.
    

    You'd want something like:

    int *alocar(void){
       int *n = malloc( sizeof(int));
       if( n == NULL )
          exit(-1);
       *n = 12;
       printf("%d.\n", *n);
       return n;
    }
    int main()
    {
       int* n;
       n = alocar();
       printf("%d.\n", *n);
       return 0;
    }
    

    Or:

    void alocar(int** n){
       *n =  malloc( sizeof(int));
       if( *n == NULL )
          exit(-1);
       **n = 12;
       printf("%d.\n", **n);
    }
    int main()
    {
       int* n;
       alocar( &n );
       printf("%d.\n", *n);
       return 0;
    }
    
    0 讨论(0)
提交回复
热议问题