[英]Delete pointer in a map<int,A*>
基本上,B是一個對象,而A是一個對象管理器,對於創建的每個對象,將在m_myMap中執行一個新條目,以便跟蹤對象的數量並能夠獲取該對象的指針。
我的問題是:我必須在A的析構函數中的m_myMap中刪除B的指針,還是如果m_myMap被自動銷毀,將不會發生內存泄漏?
啊:
#ifndef A_H
#define A_H
#include "B.h"
class B;
class A
{
public:
A();
~A();
int addB(B* myBPointer);
private:
std::map<int,B*> m_myMap;
}
#endif
BH:
#ifndef B_H
#define B_H
#include "A.h"
class A;
class B
{
public:
B(A* givenA);
~B();
private:
A *m_myA;
int m_id;
}
#enfif
B.cpp:
B::B(A* givenA)
{
m_myA = givenA;
m_id = m_myA->addB(this);
}
B::~B(){} // nothing here because m_myA is coming from another class and is destroyed in that class
A.cpp:
A::A();
A::~A()
{
for(std::map<int,B*>::iterator it = m_myMap.begin();it != m_myMap.end();++it)
delete it->second;// the program crashes
}
int A::addB(B* myBPointer)
{
m_myMap.insert(std::pair<int,B*>(m_myMap.size(),myBPointer));
return m_myMap.size()-1;
}
C.cpp和Ch:
#ifndef C_H
#define C_H
#include "A.h"
class C
{
public:
C();
void myFunction();
private:
A* my_A;
}
#endif
C::C()
{
my_A = new A;
}
void C::myFunction()
{
B myObject(my_A);
}
一個問題是:
m_myMap->erase(it);
無效it
,所以你不能安全地以后使用它。 通常,要在遍歷容器時擦除元素,請將循環結構如下
for (auto it = map.begin(); it != map.end(); /* don't increment here*/) {
delete it->second;
it = map.erase(it); // update here
}
在這種情況下,由於您還是要銷毀地圖,因此無需刪除每個元素,只需刪除它們指向的對象即可。
您也沒有遵循“三個規則” ,因此您可能會意外地復制這些對象,最終導致兩個試圖刪除同一對象。 絕對沒有理由動態分配地圖,因此將其替換為對象成員
std::map<int,B*> map;
仍然存在的問題是,復制此副本會得到兩個帶有指向相同B
對象的指針的映射。 如果沒有充分的理由進行動態分配,則將對象本身存儲在地圖中:
std::map<int,B> map;
如果確實需要動態分配(也許因為B
是基類,並且實際對象可能是各種派生類型),則可以使用智能指針( std::unique_ptr
可能是合適的),或者非常小心處理原始指針。
通常,除非確實需要,否則不要使用指針或new
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.