删除指向指针列表的指针

时间:2012-03-14 19:52:29

标签: c++

我创建了一个类,它创建了一个新的对象指针列表:

FeatureSet::FeatureSet() {
    this->featuresList = new list<HaarFeature*>;
    globalCounter = 0;
}

现在我想从列表中删除所有对象,然后删除指向列表的指针。我的代码是:

FeatureSet::~FeatureSet() {
    for (list<HaarFeature*>::iterator it = featuresList->begin(); it !=     featuresList->end(); it++) {
        delete *it;
    }
    delete featuresList; // this take a long time (more than half a minute)
}

我的问题是解决这个问题的最佳方法是什么?我的方法是否正确?不幸的是,目前最后一次操作(删除指向列表的指针)大约需要半分钟。列表有大约250000个对象。

4 个答案:

答案 0 :(得分:1)

您确实需要使用不同的数据结构。根据您的突变模式,使用dequevector等容器可能会更好。

答案 1 :(得分:1)

你的方法是正确的。这似乎是做你想做的事情的合适方式。但list解除分配是昂贵的。也许尝试不同的数据结构?

以下内容:

 for (; _Pnode != _Myhead; _Pnode = _Pnext)
 {  // delete an element
    _Pnext = _Nextnode(_Pnode);
     this->_Alnod.destroy(_Pnode);
     this->_Alnod.deallocate(_Pnode, 1);
 }

是代码大部分时间花费的地方。它需要遍历所有节点并删除它们。对于list来说,真的没办法解决这个问题。

我建议你使用std::vector,解除分配要快得多。

答案 2 :(得分:0)

鉴于您正在使用列表,是的,这是删除子元素的方法。请注意,无论您使用何种容器,如果您要存储指针,请执行“获取下一个指针并将其删除”的操作。很可能需要相同的时间。它当然值得测试作为练习。

您可以节省删除容器(以及它包含的节点)本身。但父容器的选择更可能取决于它在其他地方的用法。例如:如果您要逐个添加节点,则向量必须重新分配并复制整个指针块以维持其内部结构。

那就是说,我也同意上面关于容器本身动态分配的观点。不妨使它成为具体的成员变量。 (当然你仍然需要迭代它并删除节点子内容。但这更像是约定的功能而不是其他任何东西。

答案 3 :(得分:0)

行。所以我进行了一些研究。我刚刚测试了四种解决方案。结果如下表所示:(我无法放置图片,请点击链接)

Comparing an efficiency of list and vector containers

从表中可以看出,包含对象的向量是最快的解决方案。存储指向对象的指针比包含实际对象要慢得多。

内容:

  • 对列表中聚合的对象的顺序访问速度很慢,可能是因为它需要从指针“跳转”到指针而特定对象不必存储在连续的内存单元格中
  • 对矢量的顺序访问很快,可能是因为对象存储在线性连续存储单元中
  • 使用迭代器访问连续对象比使用索引更快,这并不奇怪
  • 存储指针而不是真实对象要慢得多,尤其是在容器的分配和释放(堆分配)期间
  • 独立于存储对象类型,列表的释放比释放向量慢得多

回答@Emile Cormier提出的问题 - 为什么我要使用指向容器的指针?这确保即使在删除父类对象后也可以访问向量/列表元素。请考虑这部分代码:

class A{
public:
A(){
    this->test = new vector<int>;
    for(int i = 0; i < 10; i++){
        test->push_back(i);
    }
}
~A(){
    cout << "object A is dead\n";
    test->clear(); // <--- COMMENTING this line allows to access to the vector's elements "after death" without copying
}
vector<int>* GetPointer(){
    return this->test;
}
private:
vector<int>* test;
};

class B{
public:
B(){
    for(int i = 0; i < 10; i++){
        test.push_back(i);
    }
}
~B(){
    cout << "object B is dead\n";
    test.clear();
}
vector<int> GetbyValue(){
    return test;
}
private:
vector<int> test;
};

cout << "\nCASE A\n";
A* instance = new A();
vector<int>* local = instance->GetPointer();
delete instance; //deletion before calling!!!
//Access is impossible, because clear method in destructor destroys original vector, connected with pointer
cout << "Printing A\n";
for(int i = 0; i < local->size(); i++){
    cout << (*local)[i] << "\n";
}
cout << "\nCASE B\n";
B* instance2 = new B();
vector<int> local2 = instance2->GetbyValue();
delete instance2; //deletion before calling!!!
//Access is still possible, because vector has been copied to local variable
cout << "Printing B\n";
for(int i = 0; i < local2.size(); i++){
    cout << (local2)[i] << "\n";
}
cout << "THE END\n";

当我不使用指向矢量的指针(情况B)时,我虽然可以在删除“B”类对象后从矢量访问对象但实际上我使用了返回矢量的本地副本。使用指向vector的指针(情况A)允许我甚至在删除“A”类对象后获得对矢量对象的访问权限,当然我当然没有手动调用析构函数中的clear()方法。

最后 - 感谢大家的帮助。我认为我的问题已经解决了。