部分损坏的对象
Partially destroyed object?
我试图理解在这个简单的情况下破坏是如何工作的:
class A {
public:
A(int i) { this->b = i; }
void p() { std::cout << a << " " << b << std::endl;}
private:
string a = "42";
int b = 0;
};
int main() {
A* ap = nullptr;
while (true) {
A k(24);
ap = &k;
k.p();
break;
} // A out of scope, I expect any pointer to A to be invalidated.
ap->p(); // still callable, b has been freed but not a!?
}
为什么 ap 确实指向部分有效的对象?我做错了什么而不理解?请准确解释,因为我是 c++ 的新手。谢谢!
编辑:假设我在~A()中调用p();这是一件安全的事情吗?
为什么 ap 确实指向部分有效的对象?
AP 不指向部分有效的对象。这是 UB。代码有效,因为即使 k 超出范围,内存也保持不变。
这里发生的情况是,当 k 超出范围时,可用堆栈内存(将放置下一个堆栈对象的位置)的内存偏移量会发生变化,因此 k(k"曾经"所在的内存")保留在可用堆栈空间中。将另一个对象放在堆栈上(在循环之后)可能会使 ap 中地址的内存失效。
UB 表示任何事情都可能发生(在这种情况下,"任何"表示 ap 指向的内存仍然指向 A::p 函数的地址。
C++本质上
不是一种引用计数的语言,因此当对象被销毁时,指针不会以任何方式直接失效。你正在诱导未定义的行为,任何事情都可能发生。编译器不需要诊断此问题。
您始终可以调用 ap->p()
,但如果不能保证 ap
指向属于 class A
实例的有效内存位置,则程序将具有未定义的行为。
未定义的行为意味着程序可以执行任何操作,包括崩溃、不执行任何操作或执行任何其他操作。
相关文章:
- 构造函数初始化和对象损坏
- 从本机代码返回到托管代码会损坏返回的对象
- 在向量中使用不带复制且没有 noexcept 移动构造函数的对象.实际损坏的内容以及我如何确认它
- 引用可能已损坏的静态对象
- 部分损坏的对象
- 对同一对象的多个shared_ptrs,一个已损坏
- C 用向量序列化对象会导致双重自由损坏
- 如何在不存在任何数据损坏风险的情况下序列化对象
- 对象, 在 Vector 中, 在'For Loop'初始化中损坏
- 我的 QNX/BB10 C++应用程序崩溃,一个简单的C++对象似乎已损坏
- 从映射中检索后,映射中的对象已损坏
- 删除对象(另一个..)时双重释放或损坏
- 多线程对象中的堆损坏
- 对象的c++内存副本出现损坏
- 对象周围的堆栈已损坏
- 在Visual Studio调试模式下运行时,c++对象引用已损坏
- 为什么在返回对象时堆损坏?
- 使用内存复制对象时出现双自由或损坏错误
- 从复制构造函数外部修改对象成员时导致向量内存损坏,但从复制构造函数内部修改时不会
- C++对象引用损坏