【发布时间】: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。
- 这是否意味着
a即使在它用完之后也不会被释放 范围。 - 这是否意味着
a仅在函数 它被定义为展开。 - 或者这是当前输出一些值的未定义行为?
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,因为指针在其指针超出范围后持有无效的指针值。该地址所在位置的内容无关紧要。