为什么悬空指针可以继续访问对象
why the dangling pointer can go on access the object?
我对野生指针和悬挂指针的一些细节感到困惑,这是我的代码:
#include <iostream>
using std::cout;
using std::endl;
class A
{
public:
void Func() { cout << "Func of class A, the address is:" << this <<endl; }
};
void Test(void)
{
A *p;
//get an error in VS2013 because of uninitialized pointer.
//But it's ok in g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
p->Func(); // wild pointer, ((1))
{
A a;
p = &a;
p->Func();
}
p->Func(); //dangling pointer ((2))
}
int main()
{
Test();
return 0;
}
结果如下:
窗口:Func of class A, the address is:003CFD47
Func of class A, the address is:003CFD47
Ubuntu:Func of class A, the address is:0xb74ef39d
Func of class A, the address is:0xbff85a3b
Func of class A, the address is:0xbff85a3b
我的问题:
(1) g++编译器让wile指针在((1))处传递,即使在运行代码时,它似乎也指向"某个对象"。为什么会发生这种情况?是编译器的错误吗?
(2) 据我所知,在块语句之后,p将是((2))处的一个悬空指针。但是为什么p可以继续指向Func()呢?因为对象a占用的空间没有被其他应用程序覆盖?
p
最初未初始化,因此它包含了为p
保留的调用堆栈区域中的任何随机值。这就是您在第一个cout
输出中看到的内容。
然后创建一个对象并将其地址分配给p
,这在第二个cout
输出中可以看到。
然后,对象超出范围并被释放,但您没有将任何内容重新分配给p
,因此它携带其现有值,您可以在第三个cout
输出中看到。
当通过无效指针调用对象方法时,尽管在技术上没有定义行为,但只要不取消引用指针以访问类的任何成员,包括任何需要VMT指针的虚拟方法,通常不会发生任何错误。
方法调用实际上只是一个带有额外隐藏的this
参数的函数调用,因此您的示例代码实际上是从编译器的角度执行以下操作:
#include <iostream>
using std::cout;
using std::endl;
class A
{
public:
static void Func(A* this) { cout.operator<<("Func of class A, the address is:").operator<<((void*)this).operator<<(&endl); }
};
void Test(void)
{
A *p; // initialized with random value
A::Func(p);
{
A a; // note: allocates only
A::A(&a); // then constructs
p = &a;
A::Func(p);
A::~A(&a);
}
A::Func(p);
}
int main()
{
Test();
return 0;
}
相关文章:
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 用于访问容器<T>数据成员的正确 API
- 访问者访问变体并返回不同类型时出错
- 循环后如何继续阅读
- 尝试通过多个向量访问变量时,向量下标超出范围
- 无法访问嵌套类.类的使用无效
- 写入位置0x0000000C时发生访问冲突
- 我们可以访问一个不存在的联盟的成员吗
- C++从另一个类访问公共静态向量的正确方法是什么
- 我的简单if-else语句是如何无法访问的代码
- 从C++dll访问C#中的一行主要参数
- 概念TS检查忽略私有访问修饰符
- 访问被拒绝后,c++中的故障保护代码
- 在c++中访问int到类对象的映射时出错
- 我想访问std::unique_ptr中的一个特定元素
- 为什么示例代码访问IUnknown中已删除的内存
- 抛出的例外:阅读访问违规.树是nullptr.如果有此例外的处理程序,则可以安全地继续该程序
- 为什么悬空指针可以继续访问对象