使用STL Queue pop()销毁类指针

时间:2015-12-30 14:06:04

标签: c++ pointers

当您通过some_queue.front()获取指针,将其分配给另一个变量,然后调用some_queue.pop()时会发生什么?谁应该清理记忆? (我正在使用c ++ 98,如果确实需要,我可以使用boost智能指针)

Ex :(为什么这样做?或者它不应该?)

class SClass {
public:
    SClass(int si): sInt(si){}
    int getSInt(){ return sInt; }

private:
    int sInt;
    ... // bunch of other complicated data types so copy might be slow
};

int main()
{
   cout << "Hello World" << endl; 
   queue<SClass *> sq;
   for(int i = 0; i < 10; i++){
       SClass *sc = new SClass(i);
       sq.push(sc);
   }
   SClass *s2 = NULL;
   while(!sq.empty()){
       s2 = sq.front();
       sq.pop();
       cout << s2->getSInt() << endl;
   }
   delete s2;
   return 0;
}

在此处运行测试代码:http://cpp.sh/6z7ke

3 个答案:

答案 0 :(得分:5)

在你的情况下,queue只管理指针本身,它对指向的内存没有任何作用。在您的示例中,您先泄漏九个SClass并仅删除最后一个。

如果您明确地需要它,则不应动态分配您的对象。试试这个:

int main()
{
   cout << "Hello World" << endl; 
   queue<SClass> sq;
   for(int i = 0; i < 10; i++){
       sq.push(i);
   }

   while(!sq.empty()){
       SClass& s2 = sq.front();
       cout << s2.getSInt() << endl;
       sq.pop();
   }
   return 0;
}

在这种情况下,对象在push编辑到队列时创建,并在pop编辑时销毁。如果我们忽略了可能的性能打嗝(临时SClass被创建为queue.push()的参数并被复制到队列内部缓冲区;这可以被优化,但它是另一个主题),这是一种更干净,更易读的方法。

如果您的对象很大并且您想确保它们没有被无用地复制,您应该使用std::queue<std::unique_ptr<SClass>>或为SClass提供移动构造函数。这有点超出范围,所以如果需要,我会让你提出另一个问题。

答案 1 :(得分:3)

  

当您通过some_queue.front()获取指针,将其分配给另一个变量,然后调用some_queue.pop()时会发生什么?

对象的副本存储在另一个变量中,并从队列顶部删除。

  

谁应该清理记忆?

分配内存的人。

  

为什么这样做?

快速浏览一下,似乎没有任何理由说明 。但是,您确实泄漏了大多数已分配的SClass个对象(除了底部之外的所有对象)。要修复泄漏,请删除从队列中获取的指针,然后再将其重新分配给另一个值(在循环结束时)。更好的是,不要手动分配内存并使用对象队列而不是指针队列。

答案 2 :(得分:3)

如果包含的元素类型是指针,则

this不会释放内存。在所有标准容器的情况下,用户必须确保释放原始指针拥有的内存。

void recursive(int i) {
    System.out.println("B.recursive(" + i + ")");
    super.recursive(i + 1);//Method of A will be called
}