C ++对象超出范围

时间:2013-11-30 09:41:06

标签: c++ scope

对象Second什么时候超出范围?如果我留下第三个cout语句,我会得到编译器错误。即使我围绕Second和cout语句的初始化。

#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;

}

运行时错误: enter image description here

3 个答案:

答案 0 :(得分:3)

以下是正在发生的事情:MyArray对象在初始化时获得一个指向它们自己的整数数组的指针,称为data。但是,此行会更改Second对象的内容:

MyArray Second = First;

现在,First.dataSecond.data都指向相同的int[]数组,因为默认的复制构造函数和赋值运算符执行副本。

这很糟糕,因为编译器可以自由地在代码中最后一次使用后销毁First。因此,访问Second.data[0]可能已无效。

此外,一旦FirstSecond超出main()末尾的范围,他们 将尝试删除data。只有第一个会成功;第二个将触发未定义的行为。

为避免将来出现此类错误,请使用rule of three。它说如果你定义了析构函数,复制构造函数或赋值运算符,你可能需要它们全部三个。

您的代码只有析构函数。添加复制构造函数和赋值运算符将解决此问题,并防止在分配MyArray对象时出现内存泄漏。

答案 1 :(得分:1)

两个名称的范围都以}结尾。 (范围是编译时的概念。)

Second的生命周期在执行到达块结束时结束,之后First的生命周期结束。但是你的程序有未定义的行为,因为你删除了两次数组,所以任何事情都可能发生。

答案 2 :(得分:1)

您需要使用复制构造函数

执行深层复制
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];
    }
   }
在此MyArray Second = First;之后

将正常工作 如果你想分配那么你也必须写作赋值运算符