unerklärliches Problem
-
Hallo,
ich versuche gerade, einen Algorithmus umzusetzen. Mit der Programmierung war ich eigentlich fertig, bis ich kompiliert habe. Mein Programm ist abgestürtzt und ich habe per Ausgaben den Ort des Fehlers gefunden. Nur kann ich nicht erklären WIESO dort ein Fehler ist. Der Code ist ein bisschen länger, deswegen poste ich einen vom aufbau gleichen Code.
void machWas( std::vector< something > &foo ) { //Hier funktioniert alles noch // foo wird geleert foo.clear(); //foo wird neu befüllt //... } void machNochEtwas( std::vector< something > &foo ) { //Ein zusätzlicher Vektor wird erstellt und gefüllt //macht irgendwas ... //Der zusätzliche Vektor wird gelöscht ( clear() ) MessageBox( NULL, "bla", "blubb", MB_OK ); //Dieses Fenster sehe ich noch. } bool controller() { std::vector< something > foo; //Vorher definieren, da ich sehr auf Performance achten muss. // "x_max" und "y_max" werden vorher berechnet. unsigned int x = 0; unsigned int y = 0; for( y = 0; y < y_max; ++y ) { for( x = 0; x < x_max; ++x ) { machWas( foo ); machNochEtwas( foo ); MessageBox( NULL, "bla", "blubb", MB_OK ); //Das hier nicht mehr!!! } } }Wie im Code steht, sehe ich die erste MessageBox, die zweite aber nicht mehr, dazwischen schreit der Debugger irgendwas von Segmentation Fault. Aber wo soll denn diese Zugriffsverletzung sein? In welchem Codeteil? Zwischen den MessageBoxen ist visuell nicht als eine "}". Da wuselt nur der Garbage Collector herum. Nur da wüsste ich nicht, wieso dieser den Fehler erzeugt.
Wenn dieser Code nichts nützt, kann ich auch den Vollständigen Code pasten, doch außer dem Inhalt dürfte da nix anders sein.
MfG. Christoph Ludwig
-
Die Referenz von machWas zeigt ja auf den Speicherbereich von foo (Zeile 24). Wenn du diese Referenz nun clearst, clearst du auch den Speicherbereich von foo (Zeile 24). Der erste Loop dürfte noch gut gehen, beim Zweiten sollte foo (Zeile 24) dann schon gecleart worden sein. Also einfach den Referenz-Operator da weg...
EDIT:
Verdammt, überlesen.EDIT2:
Wie befüllst du dein Array? Zeig mal den Code (codepad.org).
-
Es gibt in C++ direkt keinen Garbage-Collektor. Was du bestimmt meinst, ist, dass alle lokalen Vaiablen in machNochwas() wie in jeder anderen Funktion am Ende freigegeben werden. Und da muss es wohl irgendein Objekt geben, dessen Destruktor zickt.
EDIT: @Kóyaánasqatsi: foo wird in machWas() neu befüllt

-
Was für ein Garbage Collector? - C++ bietet nämlich gar keinen an.. Und wahrscheinlich liegt auch irgendwo da dein Problem.. Du scheinst die Speicherverwaltung in C++ nicht zu kennen..
-
@Kóyaánasqatsi:
Ich kann dir nicht ganz folgen. In machWas() wird foo zuerst gecleart. Danach, in der selben Funktion, wird er neu bestückt.
Aber auf die Referenz kann ich nicht verzichten, da foo in machWas() geändert wird. die änderung ist Grundlage für machNochEtwas(). Also entweder Referenz oder Pointer.@XMaster: Wenn es da ein Objekt geben würde. In dieser Funktion sind ein vector<int>, 3 Integer und 1 float-variable. mehr nicht.
Da das wohl fehlgeschlagen ist, paste ich mal den ganzen Code:
#include <vector> #include <allegro.h> struct WeichzeichnenRGB { //Die Farbewerte int r; int g; int b; //Die Gewichtung der Farbe float weighting; //Die Gruppe des Feldes int group; //Existiert dieses Pixel überhaupt? bool exist; }; void createMatrix( std::vector< WeichzeichnenRGB > &matrix, BITMAP *image, unsigned int posx, unsigned int posy, int factor ) { int x = 0; int y = 0; int x_max = ( posx + factor ); int y_max = ( posy + factor ); //Die alten Einträge in der Matrix löschen matrix.clear(); //Die Integer-Farbe, aus der später die RGB farbe berechnet wird. int color = 0; //Die Matrix mit neuen Werten belegen for( y = ( posy - factor ); y < y_max; ++y ) { for( x = ( posx - factor ); x < x_max; ++x ) { //Ein tmporäres Element, welches dann in die Matrix gelegt wird. WeichzeichnenRGB wrgb; //Existiert dieses Pixel? if( x >= 0 && y >= 0 && x < image->w && y < image->h ) { //Ja, es existiert -> Die Farbwerte auslesen color = _getpixel32( image, x, y ); //Die RGB-Werte setzen wrgb.r = getr32( color ); wrgb.g = getg32( color ); wrgb.b = getb32( color ); //Eintragen, dass das Pixel existiert. wrgb.exist = true; } else { //Nein, das Pixel existiert nicht! wrgb.exist = false; } //Die Gruppe berechnen und zuweisen wrgb.group = factor - ( ( posx - x ) + ( posy - y ) ); //Die temporären Informationen in die Matrix eintragen matrix.insert( matrix.end(), wrgb ); } } } void matrixWeight( std::vector< WeichzeichnenRGB > &matrix, int factor ) { //Die Anzahl aller Gruppen zählen std::vector<int> groupNumbers( factor, 0 ); int i = 0; int i_max = matrix.size(); for( i = 0; i < i_max; ++i ) { groupNumbers[( matrix[i].group - 1 )]++; } //Die Gesamtanzahl aller Felder berechnen int all = 0; i_max = groupNumbers.size(); for( i = 0; i < i_max; ++i ) { all += ( i + 1 ) * groupNumbers[i]; } //Den Faktor berechnen float singleFactor = 100.0 / static_cast<float>( all ); //Den Faktor zu den Gruppen speichern i_max = matrix.size(); for( i = 0; i < i_max; ++i ) { matrix[i].weighting = ( static_cast<float>( matrix[i].group ) * singleFactor ) / 100.0; } groupNumbers.clear(); allegro_message( "bla" ); } int getMatrixColor( std::vector< WeichzeichnenRGB > matrix ) { float resultR = 0.0; float resultG = 0.0; float resultB = 0.0; int i_max = matrix.size(); for( int i = 0; i < i_max; ++i ) { resultR += matrix[i].r * matrix[i].weighting; resultG += matrix[i].g * matrix[i].weighting; resultB += matrix[i].b * matrix[i].weighting; } return makecol( static_cast<int>( resultR ), static_cast<int>( resultG ), static_cast<int>( resultB ) ); } bool weichzeichnen( BITMAP *image, int factor=5 ) { //Existiert das Bild? if( image == NULL ) { return false; } if( factor <= 0 ) { return false; } //Die Werte des Bildes im richtigen Typ speichern unsigned int imageWidth = image->w; unsigned int imageHeight = image->h; //Ein temporäres Bild erzeugen, welches bemalt wird, um keine Manipulationen im Algorithmus zu erzeugen. BITMAP *tmp = create_bitmap( imageWidth, imageHeight ); if( tmp == NULL ) { return false; } clear_to_color( tmp, 0 ); //Die Schleifenzähler vorher definieren, da es sonst in der Schleife zu unnötig vielen Variablen-Erzeugungen kommt. unsigned int x = 0; unsigned int y = 0; //Mit Hilfe dieser Matrix wird die Gewichtung eingeteilt und std::vector< WeichzeichnenRGB > rgbMatrix; //Jedes Pixel soll durchlaufen werden! for( y = 0; y < imageHeight; ++y ) { for( x = 0; x < imageWidth; ++x ) { //Das aktuelle Pixel liegt nun bei image[x][y]. //Eine Matrix mit den Farbwerten der umliegenden Pixel erstellen createMatrix( rgbMatrix, image, x, y, factor ); //Die Gewichtung berechnen und den einzelnen Pixeln in der Matrix zuweisen matrixWeight( rgbMatrix, factor ); allegro_message( "blubb" ); //Die neue Farbe berechnen putpixel( tmp, x, y, getMatrixColor( rgbMatrix ) ); } } //Das temporäre Bild auf das übergeben Zeichnen draw_sprite( image, tmp, 0, 0 ); destroy_bitmap( tmp ); return true; } int main() { allegro_init(); set_color_depth( 32 ); set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 ); install_keyboard(); BITMAP *background = create_bitmap( SCREEN_W, SCREEN_H ); if( background == NULL ) return -1; clear_to_color( background, makecol( 255, 255, 255 ) ); rectfill( background, 14, 14, SCREEN_W - 15, SCREEN_H - 15, 0 ); //Das Original zeichnen draw_sprite( screen, background, 0, 0 ); while( !key[KEY_SPACE] ); //Das manipulierte Bild zeichnen weichzeichnen( background ); while( !key[KEY_ESC] ); destroy_bitmap( background ); return 0; } END_OF_MAIN()Ich hoffe, ihr könnte den Fehler jetzt finden. Ich bin mit meinem Latain em Ende

MfG. Christoph Ludwig
-
Ich hab oben den Code gepostet. Ich lösche da nur den Vektor. Der Debugger zeigt mir da auch nix an.
-
zu faul?
ich hab den Fehler gesucht, nur sagt mit der Debugger auch nix vernünftiges:
Program recieved signal SIGSEGV, Segmentation Fault
Call Stack:67A30C61 uvszprintf()
00000000 ??()Kannst du etwas damit anfangen? ich nicht. Und ich bin auch kein C++-Profi, deshalb habe ich hier lediglich gefragt. Und wenn man keine Ahnung/Erfahrung hat, kann man das NICHT faul nennen!
Ich habe hier gefragt, weil es hier Leute gibt, wie wesentlich mehr Ahnung als ich haben und den Fehler durch ihre Erfahrung finden, oder weil sie diesen Eventuell auch schon hatten. Und wenn du nicht bereit bist, mir zu helfen, dann brauchst du hier auch nicht schreiben!
-
ChristophLu schrieb:
ich hab den Fehler gesucht, nur sagt mit der Debugger auch nix vernünftiges:
Program recieved signal SIGSEGV, Segmentation Fault
Call Stack:67A30C61 uvszprintf()
00000000 ??()Debugger bedienen können gehört zum Programmieren dazu. Ein Debugger ist kein automatischer Fehlerfinder, der mit dem virtuellen Finger auf die Stelle zeigt, die falsch ist.
Dein Debugger hat doch sicher eine Funktion, um zeilen/blockweise durch den Code zu steppen? Lauf damit durch den Code und schau dir in jedem Schritt an, was passiert. So findet man Fehler.
-
Ganz nützlich ist es auch Teile zu kommentieren und wenn der Fehler immer noch da ist, dann weiter machen, bis er weg ist und dann hast du die Stelle schon fast, wo es Probleme gibt.
-
TGGC: Ist der Link für mich? Wenn ja: Willst du mich verarschen? Was soll das?
Ich hab jetzt den Fehler gefunden und der Code funktioniert einwandfrei. Ich habe viel früher falsche Berechnungen durchgeführt und habe somit falsche Indexe bei groupNumbers verwendet.
-
Du meinst die Zeile
groupNumbers[( matrix[i].group - 1 )]++;?
Ist auch sehr gefährlich, da du keinen Check auf die Indizes macht, benutze daher besser die Funktion 'at' statt [], dann kriegst du wenigstens eine Exception.
Und bei der Funktion getMatrixColor solltest du auch als Parameter eine konstante Referenz verwenden (ansonsten kopierst du jedesmal den gesamten vector):
getMatrixColor( const std::vector< WeichzeichnenRGB > &matrix )
-
Th69:
Die Indexes sind an der Stelle richtig, da ich sie vorher schon kontrolliere, sie ändern sich in der Zwischenzeit nicht.
Das mit dem const ist richtig, hab ich vergessen. Danke!TGGC:
Und deswegen schickst du ein Google-Link für das auskommentieren für Code. Hälst du mich eigentlich für total bescheuert?
-
ChristophLu schrieb:
TGGC:
Und deswegen schickst du ein Google-Link für das auskommentieren für Code. Hälst du mich eigentlich für total bescheuert?Lass dich von dem nicht ärgern, der schickt seine Linksammlung bei jedem einzelnen Post mit, ganz egal obs die Leute interessiert oder nicht. Kümmer dich eifnach nciht drum. Back to topic.

-
Hallo nochmal,
was mich noch ein bisschen stört ... ich habe groupNumbers im beispiel mit 5 Feldern initialisiert ... nach einer ausgabe der indexe waren da unterschiedliche werte von -10 bis +10.
Da sollte das Programm ja schon abstürtzen. Aber ich habe ja noch die MessageBom am Ende der Funktion gesehen. Wie ist das möglich?
-
Genau deswegen habe ich ja auf std::vector.at() hingewiesen!!!
Du schreibst dann einfach in irgendwelchen Speicher, der nicht zum vector gehört, und ob bzw. wann dann dein Programm abstürzt ist völlig undefiniert.
-
das hab ich doch gar nicht gefragt ... lies bitte richtig. In der jetzigen Version des Programmes sind die Indexe auf keinen Fall falsch ... In dem Programm vorher( der code, den ich gepostet habe ), habe ich auf Indexe von -10 bis +10 zugegriffen, obwohl nur von 0 bis 4 gültig wären. Aber dennoch ist das Programm nicht abgestürtzt( Ich habe ja noch die MessageBox danach gesehen ). Warum? Ich hatte den Speicher vorher deutlich überschritten?
Das ist die Frage.
-
ChristophLu schrieb:
Warum? Ich hatte den Speicher vorher deutlich überschritten?
Und genau darauf hat Th69 die richtige Antwort geschrieben. Der Zugriff mit falschen Indizes ist undefiniert, was nicht gleichbedeutend ist mit "das Programm stürzt ab". Undefiniert heißt eben dass alles passieren kann. Wennd er Compiler Spaß dran hat spielt dein Rechner je nach falschem Index eine beliebige Nationalhymne auf dem PC-Speaker, so er denn einen hat.
-
achso. Ich hatte gedacht, das das Programm bei sowas abstürtzt. Zumindest war das bis jetzt immer der Fall.
Aber wenn das so ist, ziehe ich alles zurück.