存储指向方法中创建的对象的指针

时间:2009-10-24 00:03:10

标签: c++

使用C ++:

我目前有一种方法,如果事件发生,则创建一个对象,并且指向该对象的指针存储在指向该类对象的指针向量中。但是,由于对象在本地作用域结束后被销毁,这是否意味着我存储到向量中的对象的指针现在为null或未定义?如果是这样,有什么通用的方法来解决这个问题 - 我假设最好的方法是在堆上进行分配。

我问这个是因为当我尝试访问向量并对内容进行操作时,我会遇到奇怪的行为,而且我不确定这是否可能是原因,或者它是否完全不相关。

5 个答案:

答案 0 :(得分:4)

这取决于您如何分配对象。如果将对象分配为自动变量(即在堆栈上),则一旦对象超出范围,任何指向该对象的指针都将变为无效,因此取消引用指针将导致未定义的行为。

例如:

Object* pointer;

{
  Object myobject;
  pointer = &myobject;
}

pointer->doSomething(); // <--- INVALID! myobject is now out of scope

但是,如果使用new运算符在堆上分配对象,则即使退出本地作用域,对象仍将保持有效。但是,请记住,C ++中没有自动垃圾收集,因此您必须记住delete对象,否则您将发生内存泄漏。

答案 1 :(得分:1)

因此,如果我理解正确,您已经描述了以下情况:

class MyClass
{
public:
  int a;
  SomeOtherClass b;
};

void Test()
{
   std::vector<MyClass*> b;
   for (int i=0; i < 10; ++i)
   {
      MyClass b;
      v.push_back(&b);
   }
   // now v holds 10 items pointers to strange and scary places. 
} 

这绝对是坏事。 有两个主要的选择:

  1. 使用new。
  2. 在堆上分配对象
  3. 使矢量保持MyClass的实例(即std::vector<MyClass>
  4. 我通常更喜欢第二种选择。这是因为我不必担心手动释放内存,向量为我做了。它通常也更有效率。唯一的问题是,我必须确保为MyClass创建一个复制构造函数。这意味着MyClass(const MyClass& other) { ... }形式的构造函数。

答案 2 :(得分:0)

如果存储指向对象的指针,并且该对象被销毁(例如超出范围),则该指针不会为null,但如果您尝试使用它,则会得到未定义的行为。因此,如果向量中的一个指针指向堆栈分配的对象,并且该对象超出范围,则该指针将无法安全使用。特别是,没有办法判断指针是否指向有效对象;你只需要编写你的程序,指针永远不会永远指向被破坏的对象。

要解决此问题,您可以使用new为堆上的对象分配空间。然后在删除它之前不会销毁它。但是,这需要一点小心才能正确,因为你必须确保你的对象不会过早被破坏(留下另一个'悬挂指针'问题,就像你现在拥有的那个)或者太晚(造成内存泄漏)。

为了解决 ,C ++中的常用方法是使用所谓的(具有不同程度的准确性) smart 指针。如果你是C ++的新手,你可能不应该担心这些,但是如果你有野心(或者对内存破坏错误感到沮丧),请查看Boost库中的shared_ptr

答案 3 :(得分:0)

如果你有一个局部变量,比如一个int计数器,那么当你退出函数时它会超出范围,但是,除非你有一个带有垃圾收集器的C ++,那么你的指针将在范围内,如你有一些指向你的对象的全局向量,只要你为指针做了new

我没有看到我做过new的情况,没有我做任何事情,我的记忆被释放了。

答案 4 :(得分:0)

检查(无特定顺序):

  • 您是否在构建存储指针的成员对象时遇到异常?

  • 您在取消引用的容器中是否有空指针?

  • 您是否在超出范围后使用vector对象? (看起来不太可能,但我仍然要问。)

  • 你正在清理吗?

以下是帮助您的示例:

void SomeClass::Erase(std::vector<YourType*> &a)
{
   for( size_t i = 0; i < a.size(); i++ ) delete a[i];
   a.clear();
}