0

I do not understand why arr is not pointing to the array I have made inside the function test:

void test(int *arr)
{
    int tmp[] = {2,4};
    arr = tmp;
    printf("%d %d\n",arr[0],arr[1]);
}

int main()
{
    int *arr;
    test(arr);
    printf("%d %d\n",arr[0],arr[1]);
    return 0;
}

When I run this program I got:

2 4
17744 786764

arr is pointer so why is not the values updated?

UPDATE: I see now that I had misunderstand a lot about pointers and variable local to a function. Have updated my small dumb script to something that works:

#include <stdio.h>
#include <stdlib.h>

void test(int *arr){
    arr[0] = 123;
    arr[1] = 321;

    printf("%d %d\n",arr[0],arr[1]);
}

int main()
{
    int arr[2];
    test(arr);
    printf("%d %d\n",arr[0],arr[1]);
    return 0;
}
2
  • Because you're passing the pointer by value - therefore you're only changing it's local copy in your test function... Commented Dec 21, 2015 at 13:05
  • And how would the copy of arr in main get updated? Commented Dec 21, 2015 at 13:05

4 Answers 4

2

Its because arguments in C are passed by value. arr you are passing in main is just copied to the function parameter arr.
The assignment arr = tmp; makes arr point to new location. Now arr is pointing to an automatic local variable and it will not exist once function reach its end.
Therefore, the statement in main

printf("%d %d\n",arr[0],arr[1]);  

invokes undefined behavior.

Change your function to

void test(int **arr)  // Change parameter to pointer to pointer to int
{
    int *tmp = malloc(2*sizeof(int));  // Allocate memory dynamically
    tmp[0] = 2;
    tmp[1] = 4;
    *arr = tmp;
    printf("%d %d\n", (*arr)[0], (*arr)[1]);
}     

and call it from main as

test(&arr);
Sign up to request clarification or add additional context in comments.

Comments

1

You pass the pointer by value (C has only pass by value) , i.e a copy of that pointer is created which points to array of integers .Therefore , there is no change at the original value of pointer in main.

If you want to you need to pass address of the pointer , but in that case also accessing it in main would also cause problem as tmp is a local variable and its scope would only remain limited to the function test.

So in main when you try to print the contents of pointer (which is uninitialized) would invoke undefined behaviour.

Comments

1

It's because in C arguments are passed by value, meaning their values are copied and the function only have the copy. Modifying a copy will of course not modify the original. In the main function, the variable will still be uninitialized when test returns, leading to undefined behavior when you try to dereference it.

C doesn't have pass by reference, but it can be emulated using pointers. In your case you must pass a pointer to the pointer.

But that's not all, you try to set the pointer to a point to a local variable, and local variables are, well, local. Their lifetime ends when the function returns, and pointers to them will not be valid once the function has returned.

There are a couple of ways to solve both of these issues. The first issue is solved by using the address-of operator to pass a pointer to the pointer, i.e.

test(&arr);

The test function must be modified accordingly to handle the pointer to pointer to int.

The second problem can be solved in a couple of ways. The simplest is to prolong the lifetime of the variable so it will live on even after the function have returned. There are basically only two ways of doing that: Make the variable a global variable, or by making it a static local variable. Another way to solve the second problem is to dynamically allocate the array using malloc, but then you will have to remember to free it once you're done with it to avoid a memory leak.

Comments

1
  1. Arguments are passed by value. Therefore, you only modify the copy and not the actual argument. To really modify arg in main, use a pointer to a pointer.
    Define your function like this:

    void test(int** arr)
    

    and dereference it in the function to modify arr from main. In addition, call test like this instead:

    test(&arr);
    
  2. Automatic variables go out of scope after a function has returned and any further access to them is undefined behavior. That means that using the array in main is undefined too.
    To prevent this, you could make the array static:

    static int tmp[] = { 0, 2 };
    

    With that, tmp is initialized only once and exists throughout the whole runtime and therefore not undefined behavior.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.