PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit dem Löschen von erzeugten Objekten



tommy@linux
02-09-2004, 16:41
hi,

also ich habe eine Klasse Object welche einen statischen Counter besitzt, der jedes Objekt zählt. Wenn das Objekt mittels delete wieder gelöscht wird, wird der Counter dekrementiert.

In meinem Programm möchte ich dynamisch Objekte erzeugen und natürlich wieder löschen. In einem STL-Vektor werden die Objekte gespeichert und mit einer Map noch mit Assoziativen Objekten verwaltet.

Wenn ich nun ein Objekt lösche, lösche ich den Eintrag in dem Vektor und in der Map, danach rufe ich die Funktion delete auf.

Da die Objekte wie in einem Baum aufgebaut sind, können sie Vaterobjekte als auch Kinderobjekte beistzen.

Das einfache Löschen funktioniert, aber wenn ich mehrere Ebenen auf einmla lösche funktioniert das genau einmal. beim nächsten Mal kommt ein Segmentation Fault welche ich noch nicht mittels gdb herausbekommen habe.

Vielleicht könnt ihr mir helfen.

Beispiel:

Objekt 1
|--------------Objekt2
|--------------Objekt3

delete... PASST

Objekt 1

hänge wieder 2 Objekte daran
Objekt 1
|--------------Objekt2
|--------------Objekt3

delete.... SEGMENTATION FAULT

locus vivendi
03-09-2004, 16:07
Könntest du versuchen, einen möglichst kurzen Code-Schnipsel zu produzieren, der das Verhalten demonstriert? Im Moment könnte noch alles mögliche die Ursache sein, ein Blick auf den Code könnte die Sache erhellen.

Vielleicht könntest du ja auch mit valgrind versuchen den Fehler zu finden.

tommy@linux
04-09-2004, 17:52
void MyFrame::OnAddObject(wxCommandEvent& WXUNUSED(event))
{
wxTreeItemId item = m_treeCtrl->GetSelection();
m_treeCtrl->CheckItem( item );

//Don't be a Assembly
int image = m_treeCtrl->GetItemImage(item);
if( image == MyTreeCtrl::TreeCtrlIcon_Folder )
{
wxTreeItemId NewItem;
NewItem = m_treeCtrl->AppendItem(item,
wxT("New Object"),
MyTreeCtrl::TreeCtrlIcon_Folder,
MyTreeCtrl::TreeCtrlIcon_Folder,
new MyTreeItemData(wxT("New Object")));

//ERZEUGE OBJECT

Group *tempGroup = new Group();
tempGroup->setNotPartOfLoadedGroup(TRUE);
tempGroup->setName("New Object");
groupVector.push_back(tempGroup);


//set Parent
map<wxTreeItemId, Node*>::iterator mapIterator;
mapIterator = idMap.find( item );

((*mapIterator).second)->addChild(tempGroup);



//id from tree and from group
idMap.insert(make_pair(NewItem, tempGroup) );

}
else
SetStatusText(_T("You can't hang a child on a Geometry-Object!"));

}

LÖSCHEN:

void MyFrame::OnDeleteChildrenRecursively(wxTreeItemId idParent, long cookie)
{

wxTreeItemId id;

if( cookie == -1 )
id = m_treeCtrl->GetFirstChild(idParent, cookie);
else
id = m_treeCtrl->GetNextChild(idParent, cookie);

if(id <= 0)
return;

if (m_treeCtrl->ItemHasChildren(id))
OnDeleteChildrenRecursively(id,-1);

/*********************************************/
wxString text = m_treeCtrl->GetItemText(id);
wxLogMessage(text);

// MapEntry
map<wxTreeItemId, Node*>::iterator mapIterator;
mapIterator = idMap.find( id );


//parentItem
wxTreeItemId parentItem = m_treeCtrl->GetItemParent(id);
map<wxTreeItemId, Node*>::iterator mapParentIterator;
mapParentIterator = idMap.find( parentItem );


// check Group or Geometry
//Group
if( ((*mapIterator).second)->getNodeType() == TYPE_GROUP)
{
Group *tempGroup = (Group *)((*mapIterator).second);

//delete from parent
((*mapParentIterator).second)->removeChild(tempGroup);

//delete from vector
vector<Group*>::iterator groupIterator;
groupIterator = find( groupVector.begin(), groupVector.end(), tempGroup );
groupVector.erase(groupIterator);

//delete from map
idMap.erase(mapIterator);

//Ohne Löschen funktioniert es, aber der Counter wird halt nicht dekremntiert...
delete tempGroup;
}

/*********************************************/

OnDeleteChildrenRecursively(idParent, cookie);
}

Also wie gesagt das erstemal geht das, aber dann..

locus vivendi
05-09-2004, 09:17
Ich kann leider keine handfesten Fehler entdecken. Ich kenn mich mit WxWidgets auch nicht aus, deshalb weiss ich nicht ob das Problem damit zu tun hat. So kann ich nur noch allgemeinere Tipps geben. Du könntest bei allen "find" oder ähnlichen Operationen den Rückgabewert überprüfen, vielleicht existiert ja ein Objekt von dem du es erwartest doch nicht (Oder machst du das in deinem richtigen Code schon und hast das bloß hier rausgenommen?). Dann castest du zwischen Node* und Group*, vielleicht liegt da ja irgendein Problem. Du könntest vielleicht einen dynamic_cast probieren. Außerdem könntest du ja mal, anstatt am Ende die Funktion mit dem selben Argument erneut aufzurufen, eine Schleife verwenden um alle "Geschwister" eines Unterbaums durchzugehen.

Ich fürchte das der Fehler wohl mit dem Code zusammenhängt der jetzt noch fehlt, oder das ich zu Blöd bin ihn zu erkennen.

Tja, ansonsten nur noch der Tipp mit valgrind. Verwendest du ein System auf dem valgrind läuft?

tommy@linux
06-09-2004, 06:12
hi,

also ich habe den Fehler endlich gefunden.

Er war aboslut nicht in dem teil des Codes wo ich gesucht habe. Im Destruktor meiner Klasse Group habe ich eine Funktion aufgerufen welche fehlerbehaftet war...

Das habe ich aber nur herausgefunden weil ich einfach so mal Objekte von der Klasse Group erzuegt und gleicvh wieder gelöscht habe.

Ja so einfach kann es manchmal sein.

Trotzdem danke für die Tipps.

PS: was macht das tool valgrind genau?

peschmae
06-09-2004, 08:54
Valgrind sucht Speichermanagementfehler.


Description: A memory debugger for x86-linux
Valgrind is a GPL'd tool to help you find memory-management problems in your
programs. When a program is run under Valgrind's supervision, all reads and
writes of memory are checked, and calls to malloc/new/free/delete are
intercepted.
.
Valgrind can debug more or less any dynamically-linked ELF Linux x86
executable, without modification, recompilation, or anything, as long as it
contains only classic x86 code (MMX/SSE/SSE2/3DNow! largely unsupported for
the moment). There is experimental support for programs using libpthread.
.
Valgrind provides a generic infrastructure for supervising the execution of
programs called "tools". This is done by providing a way to instrument
programs in very precise ways, making it relatively easy to support
activities such as dynamic error detection and profiling. Available tools
include Memcheck (a heavyweight memory checker), Cachegrind (a cache-miss
profiler), Addrcheck (a lightweight memory checker) and Helgrind (a
data-race detector), among others.


In Zukunft bitte jeweils [ code ] [ / code] Tags um deine Quelltextstücke tun, das wird damit hübscher und besser lesbar.

MfG Peschmä