【问题标题】:Is the stack variable deallocated when it goes out of scope? [duplicate]堆栈变量超出范围时是否被释放? [复制]
【发布时间】:2018-08-31 05:58:06
【问题描述】:

sample1.cpp

#include <iostream>

int main()
{
    int* aPtr = nullptr;

    {
        int a = 3;
        aPtr = &a;
    }

    std::cout << *aPtr << std::endl;

    return 0;
}

输出

3

我可以通过aPtr 访问a

  1. 这是否意味着a 即使在它用完之后也不会被释放 范围。
  2. 这是否意味着a 仅在函数 它被定义为展开。
  3. 或者这是当前输出一些值的未定义行为?

sample2.cpp

#include <iostream>

struct Box
{
    Box(int a_)
        :a(a_)
    {}

    int getValue() const { return a;}

    ~Box()
    {
        std::cout << "Destructor called" << std::endl;
    }
private:
    int a;
};


int main()
{
    Box* boxPtr = nullptr;

    {
        Box box = 23;
        boxPtr = &box;
    }

    std::cout << boxPtr->getValue() << std::endl;

    return 0;
}

输出

Destructor called
23

即使在调用box 的析构函数之后,我也可以通过boxPtr 访问box

【问题讨论】:

  • 两次未定义的行为。
  • 该内存位置仍然恰好指向数据,但它可能在任何阶段被覆盖。
  • @Vivek 顺便说一句,你不必给构造函数参数起丑陋的名字,比如a_,因为Box(int a) : a(a) {} 是完全有效的。
  • 看起来像未定义的行为,在这两种情况下都应该释放变量。
  • @MartinCook 它是 ub,因为指针在其指针超出范围后持有无效的指针值。该地址所在位置的内容无关紧要。

标签: c++ c++11


【解决方案1】:

正如 cmets 中所述,在这两种情况下,您都面临未定义的行为(因此任何事情都可以发生)。堆栈变量一旦超出范围就会被销毁,它们占用的内存被释放,尽管通常它不会立即被覆盖(至少在像上面这样的简单情况下),因此指向此类变量的指针有时可能会表现出更多或更少的“有效”属性(因为它看起来仍然有效),尽管它显然是悬空的。

【讨论】:

    猜你喜欢
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2018-10-05
    • 2013-03-30
    • 1970-01-01
    • 2019-11-26
    • 2013-11-03
    相关资源
    最近更新 更多