segfault bei free
-
hallo, ich schreibe als eine Projektarbeit an einer Bibliothek für Binäre Suchbäume bzw AVL Bäume, habe nun beim löschen ein problem bei dem ich nicht weiss woher
folgender code
//kleinstes element im rechten Teilbaum suchen (nächstgrößeres Element als ersatz suchen) node * dataSwap = findSmallest( ret->rightChild ); printf( "D2 \n" ); printf("before dataswap assert\n"); assert( dataSwap != NULL ); //altes datenelement löschen printf("before free\n"); printf("ptr: %p \n",ret->data); printf("value: %i \n",(*(int*)ret->data) ); free( ret->data); printf("after free\n");
doch beim free( ret->data ) kommt ein segfault. ich denke ich weiss nun auch woher. Das elemen was ich löschen will ist ein int aus einem array
also eingefügt wird soint i[10] = {10,13,11,5,2,1,4,90,34,32}; int j; binaryTree * myTree = newBinaryTree( &i[0] ); for ( j = 1; j < 10; ++j ) { insert( myTree, &i[j], cmp); }
ich denke also es kommt der segfault daher weil das element nicht gelöscht werden darf da es ja noch im arry vorhanden ist. oder? Kann es nicht daher stammen. Wie umgehe ich das genannte problem am besten.
-
Was genau ist 'ret' und wie hast du dessen Member mit Daten gefüllt?
-
ret ist ein node *
die funktion find nimmt ein node ** ret, sucht ein element und biegt dann halt den Zeiger auf das richtige element.
hier die deklaration, wenn gewünscht kann ich auch die implementation posten
bool find( binaryTree * tree, void * ref, int(*cmp)(void*,void*), node ** ret );
das einfügen erfolgt im grunde so
curNode->leftChild = malloc( sizeof(node) ); curNode->leftChild->parent = curNode; curNode->leftChild->leftChild = NULL; curNode->leftChild->rightChild = NULL; curNode->leftChild->data = data; return true;
also es wird ein knoten gesucht an die daten nach Suchbaum struktur angefügt werden, es wird der neue knoten erzeugt und das datenelement angehängt.
-
Dann will ich für dich hoffen, daß data ein Zeiger auf einen mit malloc() angeforderten Speicherblock ist.
-
passiert das hier nicht im grunde automatisch? Weil es ja konstant ist
int i[10] = {10,13,11,5,2,1,4,90,34,32}; int j; binaryTree * myTree = newBinaryTree( &i[0] ); for ( j = 1; j < 10; ++j ) { insert( myTree, &i[j], cmp); }
das problem ist aber halt wie ich vermute das es constant ist darf ich das nicht löschen. Wird ja im konstanten Datensegment des programms gehalten, wie könnte ich das dynamisch regeln?
-
Das Problem ist prinzipieller Art - free() darf nur auf Zeiger losgelassen werden, die von malloc() und Co. zurückgegeben wurden. In deinem Fall verwendest du die Adresse einer lokalen Variablen - die wird am Ende der umschließenden Funktion automatisch aufgeräumt und braucht (und darf) nicht per free bereinigt werden. Wenn du sehr viel Wert auf dein free() legst, kannst du auch eine Kopie des übergebenen Wertes auf den Heap packen - den darfst du dann auch selber wieder freigeben.
-
ok dann werde ich doch immer mit kopien arbeiten.... ist wohl sicherer. danke für die hilfe.