Search code examples
c++arraysfunctionvariablesvoid

Why values of array changes outside a void function while it changes inside a void function?


I am beginner in C++ programming. I wrote a simple program. I defined a function named "myFunction" and it gets an array and its size as input argument. Inside the function the first element of array changes to 100. However, in the main function the value of the first elements of the array changed. Why is that? I tought it must not change. I know that in the similar case for an int variable it does not happen.

#include <iostream>

using namespace std;

void myFunction(int a[],int b)
{
    a[0] = 100;
}

void myFunction2 (int a)
{
    a = a+2;
}

main()
{
    int size_of_array = 5;
    int myArray[size_of_array] = {7,8,2,3,5};
    int c = 2;
    myFunction(myArray,5);
    myFunction2(c);
    cout << myArray[0]<< endl;
    cout << c;
}

I expected that the first elements of "myArray" should be 7 after I called "myFunction"


Solution

  • In C++ arrays don't get passed around as values, per se. Instead your array is allocated in main as a series of five sequential (probably) 32-bit int values.

    Your myFunction function gets a pointer to the beginning of that chunk of memory, rather than a copy of the entire array. a[0] = 100; is functionally identical to *(a + 0) = 100;. You are dereferencing the pointer and assigning to it. This changes the value in memory at that address. This change reflects in main after you've called myFunction because that memory address never changed.

    The int value you passed to myFunction2 was copied. Changes made to a in that function have no effect on c in main.

    It's worth noting that variable length arrays like you've shown are not part of the C++ standard. While some compilers may support them, it's best not to count on that support.

    It would be sufficient to write the following and let the compiler figure out the size.

        int myArray[] = {7,8,2,3,5};
    

    Now, if we leave the realm of raw arrays and start using a container like std::vector, we can pass by either value or reference, and if we pass by value, you do get a copy. Consider:

    #include <vector>
    #include <iostream>
    
    void foo(std::vector<int> v) {
        v[0] = 100;
    }
    
    void bar(std::vector<int>& v) {
        v[0] = 100;
    }
    
    int main() {
        std::vector<int> v = {1, 2, 3, 4, 5};
    
        for (auto x : v) std::cout << x << std::endl;
    
        foo(v);
    
        for (auto x : v) std::cout << x << std::endl;
    
        bar(v);
    
        for (auto x : v) std::cout << x << std::endl;
    
        return 0;
    }
    

    Output:

    1
    2
    3
    4
    5
    1
    2
    3
    4
    5
    100
    2
    3
    4
    5
    

    After calling foo there is no change to v in main. But because v is passed to bar by reference, assigning to its first element does reflect in main when we print the array.