Quaxton Hale
Quaxton Hale

Reputation: 2520

C++ Object out of scope

When does the object Second go out of scope? If I leave the third cout statement I get a compiler error. Even when I surround the initialization of Second and the cout statements.

#include <iostream>
using namespace std;


class MyArray{

public:
    int Size;
    int* data;

    MyArray(int s) : Size(s), data(new int[s]){}
    ~MyArray(){
        delete[](this->data);
    }
};



int main()
{

    MyArray First(20);
    First.data[0] = 25;

    MyArray Second = First;
    cout << First.data[0] << endl;
    cout << Second.data[0] << endl;
    cout << Second.data[0] << endl;



    system("PAUSE");
    return 0;

}

The runtime error: enter image description here

Upvotes: 2

Views: 128

Answers (3)

EmptyData
EmptyData

Reputation: 2576

You need to do the deep copy using copy constructor

MyArray(const MyArray &t)
   {

    t.size = size;
    if(size not_eq 0)
    {
    t.data = new int(size);
    for(int i=0 ; i<size ; i++)
     t.data[i] = data[i];
    }
   }

after this MyArray Second = First; will work fine if you want to assign then you have to write assignment operator as well

Upvotes: 1

Alan Stokes
Alan Stokes

Reputation: 18964

The scope of both names ends at the }. (Scope is a compile-time notion.)

The lifetime of Second ends when execution reaches the end of the block, after which the lifetime of First ends. But your program has undefined behaviour because you delete the array twice, so anything can happen.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Here is what's going on: MyArray objects get a pointer to their own array of integers called data upon initialization. However, this line changes things for the Second object:

MyArray Second = First;

Now both First.data and Second.data point to the same int[] array, because the default copy constructor and assignment operator perform a shallow copy.

This is bad, because the compiler has freedom to destroy First after its last use in your code. Hence, accessing Second.data[0] may be invalid already.

Moreover, once First and Second go out of scope at the end of main(), they both will try deleting data. Only the first one would succeed; the second one will trigger undefined behavior.

To avoid such errors in the future, use the rule of three. It says that if you define a destructor, a copy constructor, or an assignment operator, you probably need all three of them.

Your code has only the destructor. Adding a copy constructor and an assignment operator will fix this problem, and prevent memory leaks on assigning MyArray objects.

Upvotes: 3

Related Questions