Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the value of a int variable through pointers passed as arguments?

Tags:

c++

pointers

I want to modify values of some variables of a particular class by accessing address of these variables from another different class through a function. So, to access this address I try to pass pointers-to-variables as arguments to a function, where these pointers-to-variables will be set with the address of the variables. To learn how to do it, I'm trying to mimic in a simple program.

Here is my code:

#include <iostream>    

using namespace std;
int numberA = 100;
int numberB = 200;

void referenceSetter(int *a, int *b)
{
    *a = numberA;
    *b = numberB;
}

void numberOutput()
{
    cout << "A = " << numberA << endl;
    cout << "B = " << numberB << endl;
}

int main() {

    int *testA = 0; 
    int *testB = 0;
    referenceSetter(testA, testB);

    *testA = 30;
    *testB = 40;
    numberOutput();

    return 0;
}

As you could see I declare numberA and numberB as global variables and set their values. The I try to get the address of these two variables through the function referenceSetter function and then after that I try to modify the values in those variables using the references. Apparently, I'm doing something wrong which leads to to have Unhandled Exception error exactly when I try to modify the values and try to set them as 30 and 40 resepectively.

Alternatively I tried the following approach:

#include <iostream>    

    using namespace std;
    int numberA = 100;
    int numberB = 200;

    void referenceSetter(int *a, int *b)
    {
        a = &numberA;
        b = &numberB;
    }

    void numberOutput()
    {
        cout << "A = " << numberA << endl;
        cout << "B = " << numberB << endl;
    }

    int main() {

        int *testA; 
        int *testB;
        referenceSetter(testA, testB);

        *testA = 30;
        *testB = 40;
        numberOutput();

        return 0;
    }

But this approach throws up the error uninitialized local variables testA and testB. Do I have to initialize pointers too?

Please help me find my mistake. Thanks.

like image 441
the_naive Avatar asked Sep 11 '15 23:09

the_naive


2 Answers

You are trying to set the contents of address 0 to be equal to the other numbers, so when you're doing *a = numberA you're assigning a value of numberA to memory address 0.

Not sure, but I think what you're trying to achieve is this:

#include <iostream>    

using namespace std;
int numberA = 100;
int numberB = 200;

void referenceSetter(int **a, int **b)
{
    *a = &numberA;
    *b = &numberB;
}

void numberOutput()
{
    cout << "A = " << numberA << endl;
    cout << "B = " << numberB << endl;
}

int main() {

    int *testA = 0;
    int *testB = 0;
    referenceSetter(&testA, &testB);
    *testA = 30;
    *testB = 40;
    numberOutput();
    return 0;
}

This way, using pointers to pointers as arguments for referenceSetter(), you are actually modifying the address that your passed pointers are pointing to.

like image 54
alesegdia Avatar answered Oct 22 '22 11:10

alesegdia


The thing you're not understanding is that pointers are passed by value, just like any other variable. If you want the passed pointer to be changed, you need to pass a pointer to a pointer (or a reference to a pointer, but I'll leave that alone, as explaining references at this point will confuse you further).

Your main() is passing NULL pointers to referenceSetter(). The assignment *a = numberA copies the value of numberA (i.e. 100) into the memory pointed to by a. Since a is a NULL pointer, that has the effect of overwriting memory that doesn't exist as far as your program is concerned. The result of that is undefined behaviour which means - according to the standard - that anything is allowed to happen. With your implementation, that is triggering an unhandled exception, probably because your host operating system is detecting that your program is writing to memory that it is not permitted to write to.

If, after the call of referenceSetter() you want testA and testB to contain the addresses of numberA and numberB respectively, you need to change referenceSetter() to something like;

void referenceSetter(int **a, int **b)
{
    *a = &numberA;
    *b = &numberB;
}

This allows the values passed to be addresses of pointers. *a then becomes a reference to the pointer passed. &numberA compute the address of numberA, rather than accessing its value 100. Similarly for numberB.

The second change is to change main() so it calls the function correctly;

referenceSetter(&testA, &testB);

which passes the address of testA (and testB) to the function, so those pointers can be changed

like image 3
Peter Avatar answered Oct 22 '22 09:10

Peter