C ++删除指针向量

时间:2011-12-28 18:51:55

标签: c++ pointers vector

这是我的代码:

#include <vector>
#include <stdio.h>
#include <iostream>

using namespace std;

class Foo 
{
public:
    Foo()
    {
    }
    ~Foo()
    {
    }
    void Bar()
    {
        cout << "bar" << endl;
    }
};

template <class T>
void deleteVectorOfPointers( T * inVectorOfPointers )
{
    typename T::iterator i;
    for ( i = inVectorOfPointers->begin() ; i < inVectorOfPointers->end(); i++ )
    {
        delete * i;
    }
    delete inVectorOfPointers;
}

int main()
{
    //create pointer to a vector of pointers to foo
    vector<Foo*>* pMyVec = new vector<Foo*>();
    //create a pointer to foo
    Foo* pMyFoo = new Foo();
    //add new foo pointer to pMyVec
    pMyVec->push_back(pMyFoo);
    //call Bar on 0th Foo element of pMyVec
    pMyVec->at(0)->Bar();
    //attempt to delete the pointers inside the vector and the vector itself
    deleteVectorOfPointers(pMyVec);
    //call Bar on 0th Foo element of pMyVec
    pMyVec->at(0)->Bar();
    //call Bar directly from the pointer created in this scope
    pMyFoo->Bar();
    return 0;
}

我试图删除一个指向矢量的指针以及矢量内的所有指针。但是,在我尝试这样做之后,Bar仍然执行得很好......

6 个答案:

答案 0 :(得分:5)

它会导致未定义的行为。这意味着任何事情都可能发生。这样:

*reinterpret_cast<int*>(0x12345678) = 314159;

也可能有用......那又怎么样?

答案 1 :(得分:2)

你指出的是一种不切实际的行为。 矢量和对象foo()确实已删除 ...

你只需要在pMyVec上写下删除的矢量的地址,这样它就可以访问你之前输入的数据了。

答案 2 :(得分:2)

上面的代码有效,因为它实际上并不依赖于那里的Foo实例。没有使用实例变量,因此它永远不会访问该内存。当然,这并不能使它安全,它只是意味着它在那个特定的实例中起作用。请看以下示例:

#include <vector>
#include <iostream>
#include <string>

using namespace std;

class Foo
{
private:
  std::string greet;    
public:
  Foo() : greet("Hello.") {}
  ~Foo() { cout << "Done." << endl; }
  void bar() { cout << greet << endl; };
};

template <class T>
void deleteVectorOfPointers(T *vector) {
  typename T::iterator i;
  for (i = vector->begin(); i < vector->end(); ++i) {
    delete *i;
  }
  delete vector;
}

int main()
{
  vector<Foo *> *myVector = new vector<Foo *>();
  Foo *testObj = new Foo();
  myVector->push_back(testObj);
  myVector->at(0)->bar();
  deleteVectorOfPointers(myVector);
  testObj->bar();
  return 0;
}

它会像预期的那样发生段错误,因为bar()试图访问不再存在的实例变量。

答案 3 :(得分:2)

对指针调用delete会将相关内存返回给内存管理库,以便它可以重用它。

指针仍然具有原始值,但它指向不再属于您的内存 访问不属于您的内存未定义。

它可能看起来像是有效的(看起来意味着它不会崩溃并给你一个结果(可能会或可能不会很好))或者它可能会导致恶魔从你的鼻子发出咕噜声。你永远不知道哪个最好不要尝试。

答案 4 :(得分:1)

值得考虑使用ptr_vector而不是存储指针的向量。

http://www.boost.org/doc/libs/1_48_0/libs/ptr_container/doc/ptr_vector.html

您应该记住,访问已删除的数据并不总是指向segfault。有时老年人没有新数据。删除没有清除内存空间。

示例内存空间:

[X _] [Y] [ž

删除Z后

[x _] [y] [ Z ]

Z 可以有效一段时间,但它是一个未定义的行为,因为 Z 现在只是垃圾。

答案 5 :(得分:0)

这个CAN工作正常只是因为你的函数Foo :: Bar真的永远不会访问对象*这个。