Reputation: 3386
To make this post a bit more constructive, and let it possibly help others in the future:
The problem was this:
std::map<Point2, Prop*> mm;
std::pair<Point2, Prop*> p;
if(Keydown(VK_LBUTTON)) {
p.first = pos; p.second = new Prop();
mm.insert(p))
}
So even though the map would get iterated over and deallocate all the Prop* pointers in the end, there were times where the insertion would fail (because a pair with the same key might already be in the tree). That means the new Prop() created, would get orphaned.
Solutions:
1) either always use std::shared_ptr (probably best solution)
2) or do this:
std::map<Point2, Prop*> mm;
std::pair<Point2, Prop*> p;
if(Keydown(VK_LBUTTON)) {
p.first = pos; p.second = new Prop();
if(mm.insert(p).second == false) {
delete p.second;
}
}
Thanks to SO user parapura rajkumar
I'm having memory leaks in my application and I don't know what's causing them! I thought I am deallocating everything I have to. The weird part is: I don't have memory leaks every time I'm running my application.
In short, this is what my app does:
On initialisation, it creates numRows
times numColumns
new Tile()
inside a TileList
.
When the mouse is hovering over some position on the screen, and the left mouse button is held, it adds a std::pair<Point2, Prop*> p
, with p.second = new Prop()
to an std::map
.
Sometimes I can just add a whole bunch of props and exit the app without any leaks. Sometimes I would add the same props as before, and it will have memory leaks upon exit.
Please help. Here is the relevant code:
If you need to see a specific part of my code, just comment it, and I'll edit the question
PropList.h
class PropList
{
protected:
std::map<Point2, Prop*> m_Props_m;
public:
PropList(){}
virtual ~PropList();
bool PropAdd(std::pair<Point2, Prop*> p)
{
pair<map<Point2, Prop*>::iterator,bool> ret = m_Props_m.insert(p);
return ret.second;
}
bool PropRemove( const Point2& pos );
bool HasProp( const Point2& pos );
void Tick();
protected:
};
static void PropRelease(const std::pair<Point2, Prop*>& p) {
delete p.second;
}
PropList.cpp
PropList::~PropList()
{
std::for_each(m_Props_m.begin(), m_Props_m.end(), &PropRelease);
}
bool PropList::PropRemove( const Point2& pos )
{
std::map<Point2, Prop*>::iterator it = m_Props_m.find(pos);
if (it == m_Props_m.end()) {
return false;
}
delete (*it).second;
m_Props_m.erase(it);
return true;
}
TileList.h
class TileList
{
protected:
std::vector<std::vector<Tile*> > m_Tiles_v;
PropList m_PropList;
UINT m_iRowNum;
UINT m_iColNum;
public:
TileList(UINT numColumns, UINT numRows);
virtual ~TileList();
//Props
void PropAdd(std::pair<Point2, Prop*> p);
void PropRemove(const Point2& pos);
bool HasProp(const Point2& pos);
void Tick();
UINT GetNumRows(){return m_iRowNum;}
UINT GetNumCols(){return m_iColNum;}
protected:
};
TileList.cpp
TileList::TileList(UINT numColumns, UINT numRows)
:m_iRowNum(numRows)
,m_iColNum(numColumns)
{
for (UINT i = 0; i < numRows; ++i) {
m_Tiles_v.push_back(std::vector<Tile*>());
for (UINT j = 0; j < numColumns; ++j) {
m_Tiles_v[i].push_back(new Tile());
}
}
}
TileList::~TileList()
{
BOOST_FOREACH(std::vector<Tile*> col_tiles_v, m_Tiles_v)
{
BOOST_FOREACH(Tile* pTile, col_tiles_v)
{
delete pTile;
}
}
}
void TileList::PropAdd(std::pair<Point2, Prop*> p)
{
if(m_PropList.PropAdd(p)) {
m_Tiles_v[p.first.y][p.first.x]->setOccupied(true);
}
}
void TileList::PropRemove(const Point2& pos)
{
if(m_PropList.PropRemove(pos)) {
m_Tiles_v[pos.y][pos.x]->setOccupied(false);
}
}
Upvotes: 6
Views: 10457
Reputation: 24433
I think you problem may lie here
bool PropAdd(std::pair<Point2, Prop*> p)
{
pair<map<Point2, Prop*>::iterator,bool> ret = m_Props_m.insert(p);
return ret.second;
}
It seems like in your code the mProps has ownership of Prop*. But if a duplicate prop is added to it will be leak because only Prop can exist for a unique Point2 and the map::insert will fail and Prop will be orphaned.
Whenever you insert pointers to object in a map or stl container. Try changing it to std::shared_ptr
for automatic memory management. In your case if you do that both your destructors don't have to a do explicit clean up and you don't need static PropRelease
at all
Upvotes: 7