-1

If I have an int array:

int *array;

array = malloc(5 * sizeof(int));

and I malloc to it as above, I can then access it and set values to it. Everything is fine.

But if I create that int pointer and pass to it a function and malloc inside the function, I can't access/set values to the array unless I pass it to the array as a pointer to a pointer?

some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

int *array;
some_void_function(array);

*(array + 3) = 5; // DOES NOT WORK

To fix it I can make the array accept (int **array) as a parameter and pass in the address of the pointer (so a pointer to a pointer), dereference it, and assign it with malloc:

some_void_function(int **array) {
    *array = malloc(5 * sizeof(int))
}

int *array;
some_void_function(&array);

*(array + 3) = 5; // WORKS 

Could someone explain this to me? Am I not doing the same thing in both situations? Pass the address and then just dereferencing it is the same thing as just pass in the single pointer in the first place right?

Zhinkk
  • 347
  • 1
  • 3
  • 11
  • How could it be the same thing, if it is not? By calling `some_void_function(array);` you are not modifying the `array`, as it is passed by value. – Eugene Sh. Feb 06 '17 at 21:38

2 Answers2

2

Pointers are variables that hold addresses. But they are subject to the same rules as all other types of variables, meaning they are passed by value.

void some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

array is local to some_void_function, and any change you make to its value isn't reflected in the pointer it was copied from.

To modify variables (pointers included) in the calling code, you have two options:

  1. Pass by pointer, which means a pointer to your pointer:

    void some_void_function(int **array) {
      *array = malloc(5 * sizeof(int))
    }
    
  2. Return the address you allocated and assign it to the pointer:

    int* some_allocating_function() {
      return malloc(5 * sizeof(int))
    }
    //...
    int *array = some_allocating_function();
    
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Just to be clear, a local copy of the *pointer* is created right? So when I do malloc inside the function I'm actually just malloc'ing to another pointer (the local one) and not the one I am expecting to malloc to? – Zhinkk Feb 06 '17 at 21:45
  • @Zhinkk - Right in one :) – StoryTeller - Unslander Monica Feb 06 '17 at 21:46
  • Sorry, this creates another confusion for me: If the pointer is passed by value, why does this work? void test(int *array) { *(array) = 10 } and in main, the array is changed. But didn't you say pointer is passed by value? – Zhinkk Feb 06 '17 at 22:11
  • 1
    @Zhinkk - You don't pass an array, you pass the address of an `int`. If it is a valid address, it can be used to modify that `int`. In the same way, if I pass the **address** of an `int *` (meaning the type is `int **`), I can use it to modify that `int *`. – StoryTeller - Unslander Monica Feb 06 '17 at 22:16
  • Perfect! Thanks for such a clear explanation. – Zhinkk Feb 06 '17 at 22:24
2

thats becuase c passes paramters by value

some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

this code just modifies the local copy of array, it doesnt change that callers copy of array

this code

some_void_function(int **array) {
    *array = malloc(5 * sizeof(int))
}

passes in the address of the callers array, this allows you to reach out of your function and change the callers array pointer

pm100
  • 48,078
  • 23
  • 82
  • 145