C++对存储的基类指针的引用出现段错误

发布于 2024-08-19 13:48:55 字数 734 浏览 5 评论 0原文

我在以下代码中通过 g++ 编译器遇到了一些令人讨厌的分段错误。关于为什么会发生这种情况以及如何解决它的任何想法都会很棒。

#include <iostream>
using namespace std;

class Base {
public:
  Base() {}
  virtual ~Base() {};
  virtual int getNum(int) = 0;
};

class Derived: public Base {
public:
  Derived() :
    Base() {}
  ~Derived() {}

  int getNum(int num) {
    return num;
  }
};

class Foo {
public:
  Foo() {
  };
  void init() {
    Derived n;
    *baseId = n;
  }
  void otherStuff() {
    cout << "The num is" << baseId->getNum(14) << baseId->getNum(15) << baseId->getNum(16) << baseId->getNum(15) << endl;
  }
  Derived* baseId;
};

int main() {
  Foo f;
  f.init();
  f.otherStuff();
  return 0;
}

I'm getting some nasty segmentation faults through the g++ compiler on the following code. Any ideas on why this would happen and how to fix it would be great.

#include <iostream>
using namespace std;

class Base {
public:
  Base() {}
  virtual ~Base() {};
  virtual int getNum(int) = 0;
};

class Derived: public Base {
public:
  Derived() :
    Base() {}
  ~Derived() {}

  int getNum(int num) {
    return num;
  }
};

class Foo {
public:
  Foo() {
  };
  void init() {
    Derived n;
    *baseId = n;
  }
  void otherStuff() {
    cout << "The num is" << baseId->getNum(14) << baseId->getNum(15) << baseId->getNum(16) << baseId->getNum(15) << endl;
  }
  Derived* baseId;
};

int main() {
  Foo f;
  f.init();
  f.otherStuff();
  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黎歌 2024-08-26 13:48:55

此处:

void init() {
    Derived n;
    *baseId = n;
}

指针 baseId 从未初始化,因此在取消引用它时会导致未定义的行为。在这里解释一下您要做什么可能是个好主意。如果您想维护一个指向派生或基类的指针,但一开始指向派生,您可以说:

void init() {
    baseId = new Derived;
}

但是您可能需要一个复制构造函数、一个赋值运算符和一个析构函数来管理该指针。

此外,出于多种原因,编写 init() 函数通常不是一个好主意 - 最好直接在构造函数或其初始化列表中完成这项工作。

Here:

void init() {
    Derived n;
    *baseId = n;
}

the pointer baseId is never initialised, resulting in undefined behaviour when you dereference it. It might be a good idea to explain what you are trying to do here. If you want to maintain a pointer to a Derived or a Base but which starts off pointing to a derived, you can say:

void init() {
    baseId = new Derived;
}

but you will then probably need a copy constructor, an assignment operator and a destructor to manage the pointer.

Also, for several reasons, writing an init() function is not normally a good idea - you are better off doing the work directly in the constructor or its initialisation list.

人生戏 2024-08-26 13:48:55

当您调用 f.init() 时,FoobaseId 成员尚未初始化,但您在 init() 中取消引用它。您确定不想要更多类似的东西吗?

baseId = new Derived()

When you call f.init(), the baseId member of Foo is not initialised, yet you dereference it in init(). Are you sure you don't want something more along the lines of:

baseId = new Derived()
阪姬 2024-08-26 13:48:55
  void init() {
    Derived n;
    *baseId = n;
  }

除了 Neil 指出的之外,派生的 n 是 init 函数的本地函数。当你退出该函数时它就会“死亡”,所以即使你正确地分配它,它也不会工作。

您想要的不是在堆栈上分配,而是在堆上分配:

  void init() {
    baseId = new Derived();
  }

甚至更好:

  void init() {
    delete baseId;
    baseId = new Derived();
  }

以及析构函数和构造函数对以防止出现问题:

Foo() : baseId(0) {};
~Foo() { delete baseId; }

如果采用此方法,请确保阻止复制构造函数和赋值运算符,或正确地实现它们。然而,要实现它们,您也需要实现 Derived 的复制 - 或者最好:使用安全的 shared_ptr 来存储指针。

  void init() {
    Derived n;
    *baseId = n;
  }

Apart from what Neil noted, derived n is local to your init function. It "dies" when you exit the function, so even if you assigned it correctly, it won't work.

What you want is not assigning on the stack but on the heap:

  void init() {
    baseId = new Derived();
  }

or even better:

  void init() {
    delete baseId;
    baseId = new Derived();
  }

and a destructor and constructor pair to prevent problems :

Foo() : baseId(0) {};
~Foo() { delete baseId; }

If going for this method, be sure to either block copy constructor and assignment operator, or implement them properly. To implement them however, you'd need to implement copying of Derived too -- or best: use a safe shared_ptr to store the pointer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文