Reputation: 2520
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:
Upvotes: 2
Views: 128
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
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
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