Fehler in der glibc ?
-
Hi !
Ich habe eine rekursive Methode geschrieben. Ich habe sie jetzt schon 3 Stunden gedebugged und 4 oder 5 mal auf nemm Blatt Papier mit nemm Baum von tausend Ästen nachvollzogen. Der Compiler beschwert sich in keinster Weise und ich kann beim besten Willen absolut keinen Fehler in meiner Methode finden.
Wenn ich das Programm aufrufe, dann erhalte ich allerdings bei der Ausführung der Methode immer und nicht zu einem festen Punkt den Fehler:
*** glibc detected *** corrupted double-linked list: 0x082ccef0 *** Speicherzugriffsfehler
Weiterhin benutze ich keinerlei doublelinked lists. Mittlierweile glaube ich fest daran, dass es ein Fehler in der glibc sein muss. 100% sicher kann ich mir natürlich nicht sein, weshalb ich hier mal nachfrage.
mfg
Tomps: poste mal hier in c++ Teil des Forums weil mein Code C++ ist.
-
tommmes schrieb:
ps: poste mal hier in c++ Teil des Forums weil mein Code C++ ist.
Da wäre dann viell auch mal bisschen C++ Code sehenswert...vielleicht liegt ja fehler doch in deinem code!
-
okay mach ich mal:
CL_Surface ist ein PNG und CL_Rect ist denke ich klar. Es handelt sich bei beiden Objekten um Objekt aus der ClanLib Library ( www.clanlib.org )
Node.h#ifndef _NODE_H_ #define _NODE_H_ #include <ClanLib/core.h> #include <ClanLib/display.h> class Node { public: CL_Rect* rect; Node** node; Node( CL_Rect* newRect ); bool isLeaf(); Node* create_NodeTree( CL_Surface* surface , CL_Rect* rect, int type ); bool check_if_subRect_occupied( CL_Surface* surface , CL_Rect* rect ); void test_check_if_subRect_occupied(); void test_create_NodeTree(); }; #endif
Die Methode in der der Fehler auftritt heiß create_NodeTree( ... ).
Node.cpp:#include "Node.h" #include <iostream> const int TRANSPARENT = 0; //integer color value for transparency const int VERTICAL_RECT = 1; //if height of a rectangle is bigger than width const int HORIZONTAL_RECT = 2; // if width of a rectangle is bigger than height Node::Node( CL_Rect* newRect ) { rect = newRect; Node** node = new Node*[4]; node[0] = 0; node[1] = 0; node[2] = 0; node[3] = 0; } /* returns true if the node we're examining is a leaf otherwise false */ bool Node::isLeaf() { //if there are no childs, we have reached a leaf if( node[0] == 0 && node[1] == 0 && node[2] == 0 && node[3] == 0 ) return true; else return false; } /* * Recursive method that builds up a tree structure of a quadTree for a surface. */ Node* Node::create_NodeTree( CL_Surface* surface , CL_Rect* rect, int type ) { Node* currNode = new Node( rect ); if( ( rect->get_width() <= 4 && type == HORIZONTAL_RECT ) || ( rect->get_height() <= 4 && type == VERTICAL_RECT ) ) return currNode; for( int j = 0 ; j < 4 ; ++j ) { CL_Rect* subRect; if( j == 0 ) { subRect = new CL_Rect( rect->left , rect->top , rect->left + rect->get_width() / 2 , rect->top + rect->get_height() / 2 ); if( check_if_subRect_occupied( surface , subRect ) ) currNode->node[ j ] = create_NodeTree( surface , subRect , type ); } if( j == 1 ) { subRect = new CL_Rect( rect->left + rect->get_width() / 2 , rect->top , rect->right , rect->top + rect->get_height() / 2 ); if( check_if_subRect_occupied( surface , subRect ) ) currNode->node[ j ] = create_NodeTree( surface , subRect , type ); } if( j == 2 ) { subRect = new CL_Rect( rect->left + rect->get_width() / 2 , rect->top + rect->get_height() / 2 , rect->right , rect->bottom ); if( check_if_subRect_occupied( surface , subRect ) ) currNode->node[ j ] = create_NodeTree( surface , subRect , type ); } if( j == 3 ) { subRect = new CL_Rect( rect->left , rect->top + rect->get_height() / 2 , rect->left + rect->get_width() / 2 , rect->bottom ); if( check_if_subRect_occupied( surface , subRect ) ) currNode->node[ j ] = create_NodeTree( surface , subRect , type ); } } //end for return currNode; } //if any pixel in the rectangle part of the current surface is NOT transparent, this method will return true, that means it is occupied bool Node::check_if_subRect_occupied( CL_Surface* surface , CL_Rect* rect ) { //for debugging this method use test_check_if_subRect_occupied() also in this class... //for simplicity... int x0 = rect->left; int x1 = rect->right; int y0 = rect->top; int y1 = rect->bottom; CL_PixelBuffer pxBuffer = surface->get_pixeldata(); //for direct pixel access we need to lock the surface. later we will unlock it. pxBuffer.lock(); //we have an argb image, which means every pixel is made out of 4 bytes. sizeof( int ) is 4 bytes ! int* pixels = (int*) pxBuffer.get_data(); for( int j = y0 ; j < y1 ; ++j ) { for( int i = x0 ; i < x1 ; ++i ) { if( pixels[ j * surface->get_width() + i ] != TRANSPARENT ) { pxBuffer.unlock(); return true; } } } pxBuffer.unlock(); return false; } void Node::test_check_if_subRect_occupied() { std::cout << "--------------( test_check_if_subRect_occupied() )--------------------\n"; CL_Surface* surface = new CL_Surface( "test.png" ); CL_Rect* rect = new CL_Rect( 0 , 0 , surface->get_width() , surface->get_height() ); if( check_if_subRect_occupied( surface , rect ) ) std::cout << "Not transparent.\n"; else std::cout << "Graphic transparent.\n"; std::cout << "--------------( end test_check_if_subRect_occupied() )--------------------\n"; } void Node::test_create_NodeTree() { std::cout << "---------------( test_build_NodeTree() )-------------------------\n"; CL_Surface* surface = new CL_Surface( "test3.png" ); CL_Rect* rect = new CL_Rect( 0 , 0 , surface->get_width() , surface->get_height() ); Node* superNode = create_NodeTree( surface , rect , HORIZONTAL_RECT); std::cout << "---------------( end test_build_NodeTree() )-------------------------\n"; }
-
Hast du das ganze mit Valgrind gecheckt? Und wie sieht der Traceback im Debugger aus?
-
ich hoffe dich störts nicht, dass ich die funktion ein bischen verändert habe sodass sie etwas übersichtlicher ist, konnte zwar keinen fehler entdecken, aber vielleicht siehst du ihn jetzt ja
Node* Node::create_NodeTree( CL_Surface* surface , CL_Rect* rect, int type ) { Node* currNode = new Node( rect ); std::size_t height=rect->get_height(); std::size_t width=rect->get_width(); std::size_t left=rect->left; std::size_t right=rect->right; std::size_t top=rect->top; std::size_t bottom=rect->bottom; if( ( width <= 4 && type == HORIZONTAL_RECT ) ||( height <= 4 && type == VERTICAL_RECT ) ) return currNode; CL_Rect* subRect[4]; subRect[0] = new CL_Rect( left , top , left + width / 2 , top + height/ 2 ); subRect[1] = new CL_Rect( left + width / 2 , top , right , top + height / 2 ); subRect[2] = new CL_Rect( left + width / 2 , top + height / 2 , right , bottom ); subRect[3] = new CL_Rect( left , top + height / 2 , left + height / 2 , bottom ); for(int j=0;j<4;++j){ if( check_if_subRect_occupied( surface , subRect[ j ] ) ) currNode->node[ j ] = create_NodeTree( surface[ j ] , subRect , type ); else delete subRect[ j ]; } return currNode; }
//edit einen fehler gefunden: wenn die bedingung check_if_subRect_occupied fehlschlägt, wird kein speicher freigegeben
//edit2 ok, ist nun korrigeirt
-
Diesen Fehler sollte man wirklich mit dem Debugger suchen. Der gdb sagt dir dann, welche Zeile und welcher Aufruf davon zu dem Fehler geführt hat. Und wenn du auch mit der Info keinen Fehler finden kannst, kannst du ja ein Update der glibc probieren.
Speicherzugriffsfehler sind aber oft ganz hinterlistige Tiere, die zu finden auch erfahreneren Kammerjägern einiges Kopfzerbrechen bereiten kann. Die glibc würde ich daher wirklich erst als allerletzte Fehlerquelle betrachten
-
vorallem, wenn man unter umständen vorher unendlich viel speicher ins datennirvana gepustet hat...
-
Hi Leute !
erstmal supervielen Dank für die netten Antworten (krass hätte nicht gedacht, dass sich jemand meine (iiih) rekursive Methode anschaut, und sogar umschreibt)Okay ich habs mal mit dem gdb versucht. Mittlerweile habe ich auch festgestellt, dass der Fehler garnicht in create_NodeTree liegt sondern in
check_if_subRect_occupied( CL_Surface* surface , CL_Rect* rect )
Nagut dann muss ich meine Testmethode noch ein bisschen erweitern.
vielen Dank
Tom
-
tommmes schrieb:
Hi Leute !
erstmal supervielen Dank für die netten Antworten (krass hätte nicht gedacht, dass sich jemand meine (iiih) rekursive Methode anschaut, und sogar umschreibt)Okay ich habs mal mit dem gdb versucht. Mittlerweile habe ich auch festgestellt, dass der Fehler garnicht in create_NodeTree liegt sondern in
check_if_subRect_occupied( CL_Surface* surface , CL_Rect* rect )
Nagut dann muss ich meine Testmethode noch ein bisschen erweitern.
vielen Dank
TomDu solltest dir mal wirklich Valgrind anschauen und alle gemeldeten Fehler beheben.