这段代码内存泄漏的原因是什么?
What caused the memory leak in this code?
我正在检查可能导致内存泄漏的代码。我知道 std::set.erase(this) 和 SomeObject 的析构函数有问题。那么如何解决呢?
class SomeObject;
////....
std::set<SomeObject*> managedObjects;
///.....
class SomeObject{
public:
SomeObject(){ managedObjects.insert(this); }
SomeObject(SomeObject&& S)/*move cter*/{ managedObjects.insert(this); }
virtual ~SomeObject() { managedObjects.erase(this); }
////....
};
////....
void clearAllObjects() {
for(auto p : managedObjects){
if(p){
delete p;
}
}
managedObjects.clear();
}
////....
当您在 clearAllObjects()
中 delete
时,它将导致 managedObjects.erase(this)
与 managedObjects.erase(p)
.
相同
这意味着基于for-loop范围内的内部迭代器可能无效(我不确定)。如果是,它将尝试对无效的迭代器执行 ++internal_iterator;
- 结果是未定义的行为。
为了安全起见,您可以在执行 erase
.
之前复制迭代器并将其移至 set
中的下一个
另请注意:无需检查您 delete
是否为 nullptr。如果是这种情况,标准规定它无效。
示例:
void clearAllObjects() {
for(auto pit = managedObjects.begin(); pit != managedObjects.end();) {
delete *pit++ // postfix ++ returns a copy of the old iterator
}
managedObjects.clear();
}
这个 managedObjects
set
的副作用是你不能有 SomeObject
.
的自动变量
int main() {
SomeObject foo;
clearAllObjects(); // deletes the automatic object "foo" (not allowed)
} // <- the automatic object is destroyed here
我正在检查可能导致内存泄漏的代码。我知道 std::set.erase(this) 和 SomeObject 的析构函数有问题。那么如何解决呢?
class SomeObject;
////....
std::set<SomeObject*> managedObjects;
///.....
class SomeObject{
public:
SomeObject(){ managedObjects.insert(this); }
SomeObject(SomeObject&& S)/*move cter*/{ managedObjects.insert(this); }
virtual ~SomeObject() { managedObjects.erase(this); }
////....
};
////....
void clearAllObjects() {
for(auto p : managedObjects){
if(p){
delete p;
}
}
managedObjects.clear();
}
////....
当您在 clearAllObjects()
中 delete
时,它将导致 managedObjects.erase(this)
与 managedObjects.erase(p)
.
这意味着基于for-loop范围内的内部迭代器可能无效(我不确定)。如果是,它将尝试对无效的迭代器执行 ++internal_iterator;
- 结果是未定义的行为。
为了安全起见,您可以在执行 erase
.
set
中的下一个
另请注意:无需检查您 delete
是否为 nullptr。如果是这种情况,标准规定它无效。
示例:
void clearAllObjects() {
for(auto pit = managedObjects.begin(); pit != managedObjects.end();) {
delete *pit++ // postfix ++ returns a copy of the old iterator
}
managedObjects.clear();
}
这个 managedObjects
set
的副作用是你不能有 SomeObject
.
int main() {
SomeObject foo;
clearAllObjects(); // deletes the automatic object "foo" (not allowed)
} // <- the automatic object is destroyed here