当您通过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
答案 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
}