Page 1 of 1

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

Posted: Sun Jan 08, 2012 4:43 pm
by Muetdhiver
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.

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

Posted: Sun Jan 08, 2012 4:55 pm
by doublemax
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

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

Posted: Sun Jan 08, 2012 7:51 pm
by Muetdhiver
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.

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

Posted: Sun Jan 08, 2012 8:02 pm
by Muetdhiver
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.

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

Posted: Mon Jan 23, 2012 5:21 am
by cdpadmin
Thanks. You saved me from lots of frustration.

Code: Select all

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

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

Posted: Mon Jan 23, 2012 2:24 pm
by Muetdhiver
Happy to help and share :).

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

Posted: Wed Jan 28, 2015 8:36 pm
by tone.garot
attr->Clone() was my salvation also.