Jump to content
  • Advertisement
Sign in to follow this  
Winegums

Passing objects to functions, C++

This topic is 3633 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I've come across something that really confuses me in C++, and yet it looks so simple. With standard data types, passing the object to a function creates a copy of the object in the function, so changes made to that object do not affect the data passed outwidth the scope of the function. ie.
void DoIt(int x)
{
    x++;
    printf("x + 1 is : %d\n", x);
}  

int main()
{
    int number = 5;  //
    DoIt(x);
    printf("number is : %d\n", number );
    return 0;
}

OUTPUT:
x + 1 is : 6
number is : 5

And that's fine and dandy. However I came across an example in which the object passed was a class instance, and the classes instance of a pointer seemed to point at rubbish when it dropped out of the function scope, and this really confused me...
class Sample
{
public:
        int *ptr;
		int mVar;

        Sample(int i)
        {
			mVar = 4;
			ptr = new int(i);
        }

        ~Sample()
        {
			delete ptr;
        }

        void PrintVal()
        {
			cout << "The value of the pointer is " << *ptr << endl
 			     << "The value of the variable is " << mVar;
       }
};

void SomeFunc(Sample x)
{
	cout << "Say i am in someFunc " << endl;
}


int main()
{

Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
char ch;
cin >> ch;
}

OUTPUT: Say i am in someFunc The value of the pointer is -17891602 The value of the variable is 4 Can anyone explain why this happens? Do non-standard data types behave differently from standard data types when passed to a function explicitly?

Share this post


Link to post
Share on other sites
Advertisement
When you enter the function, the copy constructor for Sample is called. Since you didn't specify a specific copy constructor, the default one (A bitwise copy) is used. In your case, it copies the int fine, but it also copies the pointer.

So now, you have two instances of your class, S1, in the main function, and X, in the SomeFunc function. Both of them have myVal = 4; and they also (importantly) have the same ptr.

However, when you exit your function, the normal destructor is called for the temporary instance you created by passing the class by value, deleting the pointer you had, and leaving the integer alone. Once out of the function, your class instance has had its pointer deleted, and pointing to invalid memory. So, when you attempt to print out the value again, it fails.

Once you exit SomeFunc, x is destructed with the destructor, calling delete ptr;. This also deletes the int that S1 in the main function was pointing to, and causes S1 to point to invalid memory.

To solve this problem, you should either:
Define a reasonable copy constructor of the form Sample::Sample(const Sample& other);
Or pass by const reference, like SomeFunc(const Sample& s)

This is why you should always follow the rule of three:
If you have one of the following, you should have all three: A Destructor, a Copy Constructor, and an Assignment Operator.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!