正在指向的对象内的指针在访问对象时更改内存位置

时间:2017-06-10 06:10:09

标签: c++ pointers

我正在努力使这段代码尽可能通用,以帮助未来的流浪者。

A.H

class A {
    protected:
        A* pointToAnother;
    public:
        A();
        func();
}

A.cpp

A::A() {
    pointToAnother = nullptr;
}

A::func() {
    // does something
}

B.h

#include "A.cpp" //Using A.h gave me linking errors

class B {
    protected:
        A* pointToA;
    public:
        B();
        do_something();
}

B.cpp

B::B() {
    A tmp;
    pointToA = &tmp;
}

B::do_something() {
    pointToA->func();
}

int main() {
    B test;
    B.do_something();
}

调用do_something()时,在pointToAnother->func()运行之前,pointToA->pointToAnother正确指向0x00000000。但是,一旦func()运行,pointToAnother现在指向0xcccccccc之前运行func()内部的内容,这会破坏我的程序。

我尝试实施三条规则,认为这个漏洞与破坏有关,但没有骰子。我在另一个程序中遇到了类似的问题(通过调用所述对象的函数来修改向量中的对象,仅用于向量中的先前位置,现在指向0xcccccccc)我放弃了。

由于

1 个答案:

答案 0 :(得分:1)

你有:

B::B() {
    A tmp;
    pointToA = &tmp;
}

在函数中,tmp是函数局部变量。当函数返回时,它将被删除,并在pointToA中留下悬空指针值。如果稍后取消引用指针,则调用未定义的行为。

您可以通过几种方式解决该问题。

  1. 将变量pointToA更改为objectA,即将其从指向A的指针更改为A类型的对象。

    class B {
        protected:
            A objectA;
    
  2. 使用new A分配内存并将其分配给pointToA

    B::B() {
        pointToA = new A;
    }
    
  3. 如果您使用第二种方法,请务必阅读The Rule of Three并相应更新您的课程。