unerklärliches Problem



  • 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.


Anmelden zum Antworten