作为我previous question的续集,我想在下面的代码中询问我做错了什么。
代码是,例如
void myclass1::myfun()
{
myclass2* newVar = new myclass2();
/* other code and stuff */
myvector.push_back(newVar); // myvector is a member of myclass1 and is a std::vector<myclass2*>
delete newVar;
}
但是当我运行它时,myvector返回空,除非我注释掉delete
行。
我做错了什么?
答案 0 :(得分:3)
您只想在完成使用后删除该对象。删除后,不应再尝试再次引用它。
在典型情况下,您只想在对象中放置对象本身(而不是指向对象的指针)。当您将对象添加到向量时,它将创建对象的副本,并在从向量中删除对象时自动销毁对象,或者向量本身被销毁。
答案 1 :(得分:2)
如前所述,当您已经释放内存时,您无法访问或更改内存。您必须注意在析构函数中删除对象(或额外的函数)。这是一个可以做到这一点的片段:
// this function adds the object
`void MyClass1::AddFun()
{
myClass2* Ptr = new myClass2(); // create new object via new-operator
myvector.push_back(Ptr);
}
// this function clears the entire vector
void MyClass1::ClearAllContent()
{
while (myvector.empty() == false)
{
delete myvector[myvectory.size() - 1]; // free the last object in your vector
myvector.pop_back(); // pop_back reomves the "empty"-pointer
}
}
答案 2 :(得分:2)
调用newVar的析构函数,并在调用delete时将new分配的内存返回给堆。
此时不应调用delete。在myclass1的析构函数或其他成员函数中执行。
最佳做法是:存储在向量值或智能指针中,例如boost :: shared_ptr&lt;&gt;。智能指针适合您的情况。你甚至可以不用担心删除myvector的元素,因为当myvector被破坏时它们会被正确地破坏。 示例代码是:
void myclass1::myfun()
{
myvector.push_back(boost::shared_ptr<myclass2>(new myclass2()));
}
答案 3 :(得分:1)
C ++不是C#或Java或其他什么。您正在使用原始指针,您可能不应该这样做。删除刚刚分配的对象时,它已经消失,不能再使用了。在向量中存储指向它的指针是一个错误。
答案 4 :(得分:1)
您在堆上创建了myclass2
的实例,然后将指针放入向量中。执行delete newVar;
时,您正在销毁刚刚创建的实例。但是你的向量仍然有一个指向对象所在位置的指针,指针不再有效。
当你不再需要堆上的对象时,你应该只调用delete
。
您的选择如下:
不要删除该对象。这意味着当一切都已完成使用时,您必须在程序中的某个其他位置删除它。这可能很难协调,因此您需要使用智能指针。如果要编译c ++ 0x,可以在Boost库或标准库中找到shared_ptr
。以下是在c ++ 0x中使用它的方法:
#include <vector>
#include <memory>
#include <algorithm>
#include <iostream>
int main(int argc, const char* argv[]) {
typedef std::vector<std::shared_ptr<int>> Vector;
Vector v = {
Vector::value_type(new int(2)),
Vector::value_type(new int(5))
};
std::for_each(v.begin(), v.end(), [](Vector::value_type x) {
std::cout << *x << std::endl;
});
return 0;
}
不要在堆上分配对象。相反,只需使用myclass
的实例填充向量,而不是指向myclass
的指针。现在你的矢量将是std::vector<myclass2>
。
如果您有选择,第二个选项更可取。每当矢量被销毁时,你的myclass2实例都会被销毁,这减轻了跟踪它们的麻烦。