assert "m_count > 0" failed in DecRef() when using a grid Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

assert "m_count > 0" failed in DecRef() when using a grid

Post by Muetdhiver » Sun Jan 08, 2012 4:43 pm

Hi !

I recently changed wxWidget 2.8 to use 2.9.3 and I've got a lots of assertions with this version.
I'm trying to remove them but this one makes me crazy :

I create a panel, that contains a overloaded wxGrid, my object is called CRoadMap.
Here is the Ctor of this class :

Code: Select all

CRoadMap::CRoadMap(	wxWindow*		par_po_parent,
					wxWindowID		par_o_id,
					const wxPoint&	par_ro_pos,
					const wxSize&	par_ro_size,
					long			par_l_style )
:	wxGrid( par_po_parent, par_o_id, par_ro_pos, par_ro_size, par_l_style ),
	m_uc_current_turn( 1 ),
	m_ul_total_time( 0U ),
	m_us_total_score( 0U ),
	m_us_neg( 0U )
{
	// Create the grid
	CreateGrid( 30, 13 );
	SetRowLabelSize( 0 );
	SetColLabelSize( 0 );
	// Init grid title
	SetCellSize( 0, 0, 1, GetNumberCols() );
	SetRowSize( 0, 25 );
	SetCellValue( 0, 0, _S(TLang::Get("road_map")) );

	SetCellSize( 1, 0, 2, 1);
	SetCellValue( 1, 0, _S(TLang::Get("round")) );
	SetCellSize( 1, 1, 2, 1);
	SetCellValue( 1, 1, _S(TLang::Get("draw")) );
	SetCellSize( 1, 2, 2, 1);
	SetCellValue( 1, 2, _S(TLang::Get("word_found")) );
	SetCellSize( 1, 3, 2, 1);
	SetCellValue( 1, 3, _S(TLang::Get("score")) );
	SetCellSize( 1, 4, 1, 2);
	SetCellValue( 1, 4, _S(TLang::Get("word_chosen")) );
	SetCellValue( 2, 4, _S(TLang::Get("word")) );
	SetCellValue( 2, 5, _S(TLang::Get("place")) );
	SetCellSize( 1, 6, 1, 2);
	SetCellValue( 1, 6, _S(TLang::Get("round2")) );
	SetCellValue( 2, 6, _S(TLang::Get("score")) );
	SetCellValue( 2, 7, _S(TLang::Get("negative")) );
	SetCellSize( 1, 8, 1, 2);
	SetCellValue( 1, 8, _S(TLang::Get("total")) );
	SetCellValue( 2, 8, _S(TLang::Get("score")) );
	SetCellValue( 2, 9, _S(TLang::Get("negative")) );
	SetCellSize( 1, 10, 1, 3 );
	SetCellValue( 1, 10, _S(TLang::Get("time_spent")) );
	SetCellValue( 2, 10, _S(TLang::Get("round2")) );
	SetCellValue( 2, 11, _S(TLang::Get("penality")) );
	SetCellValue( 2, 12, _S(TLang::Get("total")) );

	// Define attributes for the table title
	wxGridCellAttr* loc_po_attributes_title = new wxGridCellAttr ;
	loc_po_attributes_title->SetFont(CHMIAttributes::wxPersonalFont10DefaultNormal);
	wxColour	loc_o_grey = wxTheColourDatabase->Find( _T("K_GREY") ) ;
	loc_po_attributes_title->SetBackgroundColour( loc_o_grey );
	SetRowAttr( 0, loc_po_attributes_title );

	// Define attributes for the first and second rows
	wxGridCellAttr* loc_po_attributes = new wxGridCellAttr ;
	loc_po_attributes->SetFont(CHMIAttributes::wxPersonalFont8DefaultBold);
	loc_po_attributes->SetBackgroundColour( loc_o_grey );
	SetRowAttr( 1, loc_po_attributes );
	SetRowAttr( 2, loc_po_attributes );

	// Automatic resize all columns except the first one
	AutoSizeColumns();
	SetColSize( 0, 20 );
    SetColMinimalWidth(0, 20);

	// Align all cells to center
	SetDefaultCellAlignment( wxALIGN_CENTER, wxALIGN_CENTER );

	// All cells are read only
	EnableEditing( false );
}


When I close my panel, I've got this assert message :
ASSERT INFO:
../src/common/object.cpp(353): assert "m_count > 0" failed in DecRef(): invalid ref data count

BACKTRACE:
[1] wxOnAssert(char const*, int, char const*, char const*, char const*)
[2] wxRefCounter::DecRef()
[3] wxGridRowOrColAttrData::~wxGridRowOrColAttrData()
[4] wxGridCellAttrProvider::~wxGridCellAttrProvider()
[5] wxGridCellAttrProvider::~wxGridCellAttrProvider()
[6] wxGridTableBase::~wxGridTableBase()
[7] wxGridStringTable::~wxGridStringTable()
[8] wxGrid::~wxGrid()
[9] ~CRoadMap() /home/stalex/Documents/prog/Krablenet/Includes/Scrabble/hmi/CRoadMap.h:9
[10] ~CRoadMap() /home/stalex/Documents/prog/Krablenet/Includes/Scrabble/hmi/CRoadMap.h:9
[11] wxWindowBase::Destroy()
[12] wxWindowBase::DestroyChildren()
[13] wxWindow::~wxWindow()
[14] ~wxNavigationEnabled() /usr/local/include/wx-2.9/wx/containr.h:161
[15] ~wxPanelBase() /usr/local/include/wx-2.9/wx/panel.h:31
[16] ~wxPanel() /usr/local/include/wx-2.9/wx/generic/panelg.h:17
[17] ~CTopingPanel() /home/stalex/Documents/prog/Krablenet/Includes/Scrabble/hmi/CTopingPanel.h:24
[18] ~CTopingPanel() /home/stalex/Documents/prog/Krablenet/Includes/Scrabble/hmi/CTopingPanel.h:24
[19] wxBookCtrlBase::DeletePage(unsigned long)
[20] wxNotebook::DeleteAllPages()
[21] wxNotebook::~wxNotebook()
[22] wxNotebook::~wxNotebook()
[23] wxWindowBase::Destroy()
[24] wxWindowBase::DestroyChildren()
[25] wxWindow::~wxWindow()
[26] ~wxNavigationEnabled() /usr/local/include/wx-2.9/wx/containr.h:161
[27] ~wxPanelBase() /usr/local/include/wx-2.9/wx/panel.h:31
[28] ~wxPanel() /usr/local/include/wx-2.9/wx/generic/panelg.h:17
[29] ~CGenericTabPanel() /home/stalex/Documents/prog/Krablenet/Includes/Common/hmi/CGenericTabPanel.h:16
[30] ~CGamePanel() /home/stalex/Documents/prog/Krablenet/Debug/../Sources/Scrabble/hmi/CGamePanel.cpp:58
[31] ~CGamePanel() /home/stalex/Documents/prog/Krablenet/Debug/../Sources/Scrabble/hmi/CGamePanel.cpp:58
[32] wxBookCtrlBase::DeletePage(unsigned long)
[33] CMainFrame::Remove_Tab_Panel(CGenericTabPanel*) /home/stalex/Documents/prog/Krablenet/Debug/../Sources/Common/hmi/CMainFrame.cpp:187
[34] CGenericTabPanel::OnClose(wxCloseEvent&) /home/stalex/Documents/prog/Krablenet/Debug/../Sources/Common/hmi/CGenericTabPanel.cpp:51
[35] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) cons)
[36] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[37] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[38] wxEvtHandler::ProcessEventLocally(wxEvent&)
[39] wxEvtHandler::ProcessEvent(wxEvent&)
[40] wxEvtHandler::SafelyProcessEvent(wxEvent&)
[41] wxWindowBase::Close(bool)
[42] CGamePanel::OnQuit(wxCommandEvent&) /home/stalex/Documents/prog/Krablenet/Debug/../Sources/Scrabble/hmi/CGamePanel.cpp:76
[43] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) cons)
[44] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[45] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[46] wxEvtHandler::ProcessEventLocally(wxEvent&)
[47] wxEvtHandler::ProcessEvent(wxEvent&)
[48] wxWindowBase::TryAfter(wxEvent&)
[49] wxEvtHandler::SafelyProcessEvent(wxEvent&)
[50] wxgtk_button_clicked_callback() button.cpp
[51] g_closure_invoke()
[52] g_signal_emit_valist()
[53] g_signal_emit()
[54] g_closure_invoke()
[55] g_signal_emit_valist()
[56] g_signal_emit()
[57] g_closure_invoke()
[58] g_signal_emit_valist()
[59] g_signal_emit()
[60] gtk_propagate_event()
[61] gtk_main_do_event()
[62] g_main_context_dispatch()
[63] g_main_loop_run()
[64] gtk_main()
But I don't understand what is going wrong.

My panel is in a notebook, and I simply call DeletePage on this notebook to remove this panel (and so, close the page, memory speaking).
It seems forbidden to delete a page that contains a grid ?
In this case how to do to close the page and avoid memory leaks ?

I've got other panels in my notebook with a lots of objects into, but no grid, and there is no error nor assertion when removing these pages.

Thanks a lot for your help.
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3

User avatar
doublemax
Moderator
Moderator
Posts: 15277
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by doublemax » Sun Jan 08, 2012 4:55 pm

The assert message is pretty clear, you just have to find out what you did wrong ;)

Are you using wxGridCellAttrProvider::GetAttr() anywhere? Docs say:
Notice that the caller must call DecRef() on the returned pointer if it is non-NULL.
http://docs.wxwidgets.org/trunk/classwx ... 6211b6ab0a
Use the source, Luke!

Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by Muetdhiver » Sun Jan 08, 2012 7:51 pm

Hi, thanks for the answer.

Yes, the message is pretty clear, but I don't find the error ! To my mind, it means that I delete two times the same object, but I don't understand where. My object (the grid) is deleted when the page of the notebook is removed, that is ok, but there is something wrong elsewhere.

Doublemax, wxGridCellAttrProvider is clearly written in the assertion backtrace, but I never use it in my own code, nor GetAttr function. That why I don't understand.
In my overloaded class (CRoadMap that inherits from wxGrid), I don't do any deletion.

But I use attributes for cells, like this, in the constructor of my class :

Code: Select all

 wxGridCellAttr* loc_po_attributes_title = new wxGridCellAttr ;
   loc_po_attributes_title->SetFont(CHMIAttributes::wxPersonalFont10DefaultNormal);
   wxColour   loc_o_grey = wxTheColourDatabase->Find( _T("K_GREY") ) ;
   loc_po_attributes_title->SetBackgroundColour( loc_o_grey );
   SetRowAttr( 0, loc_po_attributes_title );
I tried to comment out this code and the assertion does not occur anymore !!!
Could you point me out what is wrong in these lines of code ?

Again thanks for your help.
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3

Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by Muetdhiver » Sun Jan 08, 2012 8:02 pm

OMG, I found where the problem is !!!

In fact, it was in this code :

Code: Select all

   wxGridCellAttr* loc_po_attributes = new wxGridCellAttr ;
   loc_po_attributes->SetFont(CHMIAttributes::wxPersonalFont8DefaultBold);
   loc_po_attributes->SetBackgroundColour( loc_o_grey );
   SetRowAttr( 1, loc_po_attributes );
   SetRowAttr( 2, loc_po_attributes );
because one attributes is used for setting 2 rows attr....
So, just doing

Code: Select all

   SetRowAttr( 2, loc_po_attributes->Clone() );
works !!

Again thanks for the help.
Bye.
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3

cdpadmin
In need of some credit
In need of some credit
Posts: 4
Joined: Mon Jan 23, 2012 5:14 am

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by cdpadmin » Mon Jan 23, 2012 5:21 am

Thanks. You saved me from lots of frustration.

Code: Select all

gridBin->SetColAttr(OPEN_GRID_DESC,left_grid->Clone());

Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by Muetdhiver » Mon Jan 23, 2012 2:24 pm

Happy to help and share :).
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3

tone.garot
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Dec 11, 2014 4:53 pm

Re: assert "m_count > 0" failed in DecRef() when using a gri

Post by tone.garot » Wed Jan 28, 2015 8:36 pm

attr->Clone() was my salvation also.

Post Reply