Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ array initialized in function cannot be accessed in main

Tags:

c++

arrays

I have a function used to initialize array in C++. after the initialization, main can not access the data in the array. Don't know why. Any help?

void testArray(int *listPtr)

{
   listPtr=new int[2]; 
   listPtr[0]=0;
   listPtr[1]=1;


}// end testArray

void main()
{
   int *list;
   testArray(list);
   cout<<list[0]<<list[1]<<endl; // this gives some random output
} // end main
like image 428
user3897933 Avatar asked Aug 03 '14 00:08

user3897933


2 Answers

You need pass by reference, so that the change to the pointer listPtr itself can be passed out to the outter variable. Remember, you are changing the value of "the pointer itself", which is invisible to the caller if pass by value.

void testArray(int * &listPtr)
{
   listPtr=new int[2]; 
   listPtr[0]=0;
   listPtr[1]=1;
}// end testArray
like image 28
Eric Z Avatar answered Sep 28 '22 03:09

Eric Z


This is because the pointer is passed by value. The argument to the function is copied, and the first line of your function replaces the local copy of the pointer with the result of the new expression. The original copy of your pointer, back in main(), is unaffected by this.

You can "fix" this by either passing the pointer by reference:

void testArray(int*& listPtr)
{

    listPtr = new int[2]; 
    // ...
}

int main()
{
    int* list = 0;
    testArray(list);
    // ...
    delete list;
    return 0;
}

or by passing a pointer to the pointer:

void testArray(int** listPtr)
{
    *listPtr = new int[2];
    // ...
}

int main()
{
    int* list = 0;
    testArray(&list);
    // ...
    delete list;
    return 0;
}

or, better still, by using a C++ standard library container that provides value semantics (in conjunction with a reference argument):

void testVec(std::vector<int>& list)
{
    list.resize(2);
    list[0] = 0;
    list[1] = 1;
}

int main()
{
    std::vector<int> list;
    testVec(list);
    // ...
    return 0;
}

Analogy time:

The problem arises because a pointer is a separate entity (object) that points to some other object. Pointers can be copied just as regular objects can, and there is no special consideration given to them to make sure that the thing they point to is updated to reflect any change made to the pointer. A reference is a different beast entirely. Once a reference has been bound to some object, it is (to all intents and purposes) indistinguishable from the object itself; any operation on the reference is an operation on the underlying object. You can think of it as though you possess a cat named Fluffy, and you let your friend borrow Fluffy; but your friend calls her Buffy. It's the same cat, and if your friend trims her claws, the next time you see Fluffy, she'll have trimmed claws.

For the pointer example, you have Fluffy, and you give your friend a note with Fluffy's address written on it. Your friend goes and gets a new cat, and writes the new cat's address on top of the note you gave them. Now, when your friend trims the claws of the new cat, nothing at all happens to Fluffy. The note just allows your friend to go to the place where Fluffy lives; right up to the point where your friend overwrites the note with the address of some other cat.

References make it much easier to reason about the behaviour of your code, and should be preferred in almost all situations.

like image 181
Andrew Avatar answered Sep 28 '22 04:09

Andrew