【问题标题】:why the dangling pointer can go on access the object? [duplicate]为什么悬空指针可以继续访问对象? [复制]
【发布时间】:2014-10-29 08:01:38
【问题描述】:

我对野指针和悬空指针的一些细节感到困惑,这是我的代码:

#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)) 处传递,即使在运行代码时,它似乎也指向“某个对象”。为什么会发生这种情况?是编译器的bug吗?

(2) 据我所知,在分块语句之后,p 将是 ((2)) 处的悬空指针。但是为什么 p 可以继续指向 Func() 呢?因为对象a占用的空间没有被其他应用程序覆盖?

【问题讨论】:

  • 这是未定义的行为。
  • 哪个是?悬空指针?@πάνταῥεῖ
  • @wjk 访问/取消引用它。
  • 但是这里的 p 在开始时没有初始化。一些帮助,我会看看它。谢谢。@AntonSavin
  • 那么既然它是未定义的,编译器可以做任何事情吗?@πάνταῥεῖ

标签: c++ pointers


【解决方案1】:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-27
    • 2014-04-10
    • 2021-12-18
    • 2014-05-14
    • 2021-02-09
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多