【问题标题】:Why there is still valid access to struct after leaving the scope? [duplicate]为什么离开范围后仍然可以有效访问结构? [复制]
【发布时间】:2014-01-07 07:54:17
【问题描述】:

首先,我想了解为什么我在输出中得到第 (5) 行和第 (6) 行,而不仅仅是其中一个。 其次,为什么mc1.print() 打印有效值? _ms 不应该指向 mc1(&MyStruct(mc2)) 之后的未定义位置,因为创建 MyStruct 的位置(在 cast 运算符中)已经展开?

struct MyStruct
{
    int w;
    int h;

    MyStruct()
    {
        cout << "MyStruct" << endl;
    }
    ~MyStruct()
    {
        cout << "~MyStruct: w=" << w << "h=" << h << endl;;
    }
};

class MyClass1
{
public:
    MyClass1(MyStruct* ms)
        :_ms(ms)
    {
        cout << "MyClass1" << endl;;
    }
    ~MyClass1()
    {
        cout << "~MyClass1" << endl;
    }

    void print()
    {
        cout << "print: w=" << _ms->w << "h=" << _ms->h << endl;
    }

    MyStruct* _ms;
};

class MyClass2
{
public:
    MyClass2()
    {
        cout << "MyClass2" << endl;
    }
    ~MyClass2()
    {
        cout << "~MyClass2" << endl;
    }

    operator MyStruct()
    {
        MyStruct ms;
        ms.h = 11;
        ms.w = 22;;
        return ms;
    }
};

int main()
{
    MyClass2 mc2;   
    MyClass1 mc1(&MyStruct(mc2));

    mc1.print();

    return 0;
}

输出是

1.    MyClass2
2.    MyStruct
3.   ~MyStruct: w=22h=11
4.    MyClass1
5.    ~MyStruct: w=22h=11
6.    ~MyStruct: w=22h=11
7.    print: w=22h=11

【问题讨论】:

  • 您所做的事情会导致未定义的行为,因为您取消引用指向 print 中的临时值的指针。它可能看起来有效,也可能无效。一切皆有可能。
  • 考虑复制构造函数。

标签: c++ operator-overloading destructor


【解决方案1】:

为什么离开作用域后结构体仍然有效?

没有。它不是有效的。您可以尝试读取任意内存地址,但这样做是无效的”。C++ 标准只是没有说明如果您执行“无效”操作会发生什么。因此您的代码可以执行您正在观察的操作。

【讨论】:

    【解决方案2】:

    首先,我想了解为什么我在输出中得到第 (5) 行和第 (6) 行,而不仅仅是其中一个。

    我不知道。 I don't,但由于程序有未定义的行为,原则上任何事情都可能发生。

    第二,为什么mc1.print()会打印有效值?

    它没有。如果该内存仍然可以访问,它会通过打印曾经被死临时占用的内存中的任何内容来提供未定义的行为。在你的情况下,只是碰巧没有任何东西重用或以其他方式使内存无效,所以你碰巧看到你在临时文件还活着时放在那里的值。

    不应该_ms 指向mc1(&amp;MyStruct(mc2)) 之后的未定义位置,因为创建MyStruct 的位置(在演员运算符中)已经展开?

    它指向某个不再包含有效对象的内存位置。通常,堆栈帧在函数返回之前不会被释放;即使是这样,内存通常仍然可以访问。所以访问一个死对象会给你某种未定义的行为,这可能不是你认为它应该给出的任何未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-03
      • 2013-04-12
      • 2012-04-29
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 2020-08-28
      • 2010-10-08
      相关资源
      最近更新 更多