Segementation Fault SDL C [gelöst]



  • Hi!!
    Ich habe ne Frage!
    Wiso Gibt dieses Programm auf Zeile 41 Segementation Fault aus ):
    und wie kann ich es beheben

    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL/SDL.h>
    #include "SDL/SDL_ttf.h"
    
    int main(){
    
    	char punkte[100];
    	char versuche[3]; // 3 stellen
    	int score;
    	int i, j, k, tcX, tcY;
    	int auflosungX;
    	int auflosungY;
    	Uint8 *keys;
    	keys = SDL_GetKeyState(NULL);
    
    	SDL_Event event;
    
    	SDL_Rect player, pong[50], textpos, trytextpos, target[11][5], **modi;
    	SDL_Surface *screen, *text, *tryrect;
    
    	SDL_INIT_VIDEO;
    
    	screen=SDL_SetVideoMode (auflosungX, auflosungY, 16, SDL_HWSURFACE | SDL_NOFRAME | SDL_DOUBLEBUF);
    	modi = SDL_ListModes (NULL, SDL_HWSURFACE|SDL_FULLSCREEN|SDL_OPENGL); // größtmögliche auflösung annehmen
    
    	auflosungX = modi[0] -> w;
    	auflosungY = modi[0] -> h;
    
    	int pongX, pongY;
    	int speed =  auflosungY /128;
    
    	TTF_Init();
    	SDL_Color color = { 255, 255, 255 }; //Weißer Text
    
    	TTF_Font *font=TTF_OpenFont("arial.otf", 150);
    	while(1)
    	{
    		printf("vor\n"); // debug
    		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); // hier segementation fault
    		printf("nach\n"); // debug
    		int allesvoll = 0;
    		int vorscore = 0; 
    		int XSpeed = auflosungX /500;
    		int YSpeed = auflosungY / 500;
    		char try = 2;
    
    		pong[0].x = 1;
    		pong[0].y = 1;
    		pong[0].w = ( auflosungX / 100 );
    		pong[0].h = ( auflosungX / 100 );
    
    		anfang:; // für den unwahrscheinlichen fall das irgendjemand den ersten block schafft
    
    		int vortry = 3;
    		try++;
    		allesvoll = 0;
    
    		pongX = rand() % (( auflosungX/ 2) - (auflosungX / 150)) *2;
    		pongY = rand() % (( auflosungY - (( ( auflosungY -10 ) / 3) * 2 )) + 15);
    
    		player.x = ( auflosungX / 2 ) - ( ( auflosungX / 6.5 ) / 2 );
    		player.y = ( auflosungY / 10 ) * 9;
    		player.h = 10;
    		player.w = ( auflosungX / 6 ) ;
    
    		target[0][0].x = auflosungX/ 4;
    		target[0][0].y = auflosungX /5;
    		target[0][0].h = auflosungX / 40;
    		target[0][0].w = ((auflosungX / 50 )* 2);
    
    		for ( tcX = 1; tcX <= 10; tcX ++)
    		{
    			for ( tcY = 0; tcY <= 4; tcY ++)
    			{
    			target[tcX][tcY].x = target[0][0].x + ((target[0][0].w + 1) * tcX);
    			target[tcX][tcY].y = target[0][0].y + ( (target[0][0].h + 1) * tcY);
    			target[tcX][tcY].h = target[0][0].h;
    			target[tcX][tcY].w = target[0][0].w;
    			SDL_FillRect(screen, &target[tcX][tcY], SDL_MapRGB(screen->format, 255, 255, 255));
    
    			}	
    		}
    		textpos.x = auflosungX / 38;
    		textpos.y = auflosungY / 21;
    
    		trytextpos.x = auflosungX - 160;
    		trytextpos.y = textpos.y;
    
    		while (try != 0) 
    		{
    
    			if (try != vortry)
    			{
    				try = vortry;
    				SDL_FillRect(screen, &trytextpos, SDL_MapRGB(screen->format, 0, 0, 0));
    			}
    			SDL_ShowCursor(0); // keinen Curser anzeigen
    			SDL_FillRect(screen, &player, SDL_MapRGB(screen->format, 0, 0, 0)); // hintergrundfarbe
    
    			for ( i = 0; i < speed; i++) // PONGBEWEGUNG
    			{
    				if ( pong[0].x <= 0 )
    				{
    					XSpeed = -XSpeed;
    				}
    				if ( pong[0].x + pong[0].w >= auflosungX)
    				{
    					XSpeed = -XSpeed;
    				}
    				if ( pong[0].y <= 0 )
    				{
    					YSpeed = -YSpeed ;
    				}
    				if ( pong[0].y + pong[0].h >= auflosungY)
    				{	
    					sleep(1);
    					vortry--;
    					YSpeed = -YSpeed ;
    				}
    
    				pong[0].x = pong[0].x + XSpeed;
    				pong[0].y = pong[0].y + YSpeed;
    				for ( j = 49; j > 0; j--) // schweif
    				{
    					pong[j].x = pong[j-1].x;
    					pong[j].y = pong[j-1].y;
    					pong[j].h = pong[j-1].h;
    					pong[j].w = pong[j-1].w;
    					SDL_FillRect(screen, &pong[j], SDL_MapRGB(screen->format, 255 - ((j *5) + 1), 255 -  ((j *5) + 1) , 255  - ((j *5) + 1))); // Farbe für den Pongschweif
    					if ( j == 49)
    					{
    						SDL_FillRect(screen, &pong[j], SDL_MapRGB(screen->format, 0,0,0)); // Farbe für den Pongschweif
    					}
    				}
    
    				if( pong[0].x + pong[0].w >= player.x && pong[0].x <= player.x + player.w) // Schlägerberührung??
    				{
    					if (pong[0].y + pong[0].h >= player.y) // gleich dem schläger
    					{
    						if (pong[0].y + pong[0].h <= player.y + (YSpeed * 2)) // gleich dem schläger
    						{
    							YSpeed = -YSpeed;
    							if ( SDL_MOUSEMOTION && event.motion.xrel /10 != 0) 
    							{
    								XSpeed = ( XSpeed + event.motion.xrel ) / 10;	
    							}
    						}
    					}
    				}
    					for ( tcX = 1; tcX <= 10; tcX ++)
    				{
    					for ( tcY = 0; tcY <= 4; tcY ++)
    					{
    
    						target[tcX][tcY].h = target[0][0].h;
    						target[tcX][tcY].w = target[0][0].w;
    						SDL_FillRect(screen, &target[tcX][tcY], SDL_MapRGB(screen->format, 255, 255, 255));
    
    						if ( pong[0].x >= target[tcX][tcY].x && pong[0].x <= target[tcX][tcY].x + target[tcX][tcY].w)
    						{
    							if ( pong[0].y >= target[tcX][tcY].y && pong[0].y <= target[tcX][tcY].y + target[tcX][tcY].h)
    							{
    							target[tcX][tcY].h = 0;
    							target[tcX][tcY].x = auflosungX; // weg vom screen
    							target[tcX][tcY].y = auflosungY; // weg vom screen
    							SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); // HintergrundFarbe
    							vorscore = vorscore + 100;
    							}
    						}
    						if ( target[tcX][tcY].h == 0)
    						{
    							allesvoll++;
    						}
    					}
    				}
    				allesvoll++;
    				if ( allesvoll > 50)
    				{
    					goto anfang;
    				}
    				allesvoll = 0;
    			}
    
    			if ( SDL_MOUSEMOTION ) 
    			{
    				if (  ( ( event.motion.x + player.w ) > auflosungX ) )
    				{
    					player.x = auflosungX - player.w;
    				}
    				else
    				{
    					player.x = event.motion.x;
    				}
    			}
    			if ( XSpeed >= 7 )	
    			{
    				XSpeed = 7;
    			}
    			if ( XSpeed <= -7 )
    			{
    				XSpeed = -7;
    			}
    			if (  vorscore != score ) 
    			{
    				SDL_FillRect(screen, &textpos, SDL_MapRGB(screen->format, 0, 0, 0));
    				score = vorscore;
    			}
    
    			sprintf(versuche,"%i", try); // score in int umwandeln
    			tryrect = TTF_RenderText_Solid(font, versuche, color);
    			SDL_BlitSurface(tryrect,NULL,screen,&trytextpos);
    
    			sprintf(punkte,"%i", score); // score in int umwandeln
    			text = TTF_RenderText_Solid(font, punkte, color);
    			SDL_BlitSurface(text,NULL,screen,&textpos);
    
    			SDL_FillRect(screen, &player, SDL_MapRGB(screen->format, 255, 255, 255));
    
    			SDL_UpdateRect(screen, 0, 0, 0, 0);
    			while ( SDL_PollEvent(&event) )
    			{
    				switch( event.type )
    				{
    					case SDL_QUIT:
    					break;
    				}
    
    				if ( keys[SDLK_q] )
    				{
    					printf("Ende Durch Abbruch!\n");
    					exit(1);
    				}
    				if ( keys[SDLK_r] )
    				{
    					vortry = 0;
    				}
    			}
    		}
    	}
    }
    

    tut mir leid wenn der code nen bisschen lang ist



  • Du setzst den Videomodus mit ungültigen parametern. Daher ist der Zeiger screen NULL. Wenn du diesen in der Zeile nr. 41 dereferenzierst kommts zu nem segfault.

    mfg
    Alex



  • Schau dir diese stelle nochmal genau an.

    int auflosungX; 
        int auflosungY; 
        Uint8 *keys; 
        keys = SDL_GetKeyState(NULL); 
    
        SDL_Event event; 
    
        SDL_Rect player, pong[50], textpos, trytextpos, target[11][5], **modi; 
        SDL_Surface *screen, *text, *tryrect; 
    
        SDL_INIT_VIDEO; 
    
        screen=SDL_SetVideoMode (auflosungX, auflosungY, 16, SDL_HWSURFACE | SDL_NOFRAME | SDL_DOUBLEBUF); 
        modi = SDL_ListModes (NULL, SDL_HWSURFACE|SDL_FULLSCREEN|SDL_OPENGL); // größtmögliche auflösung annehmen 
    
        auflosungX = modi[0] -> w; 
        auflosungY = modi[0] -> h;
    

    auflosungX und auflosungY werden erst nach SDL_SetVideoMode mit werten gefüllt.



  • c0ff33.alex schrieb:

    Du setzst den Videomodus mit ungültigen parametern. Daher ist der Zeiger screen NULL. Wenn du diesen in der Zeile nr. 41 dereferenzierst kommts zu nem segfault.

    mfg
    Alex

    danke!
    aber was für ungültige parameter meinst du denn?
    wie würde es denn richtig aussehen?



  • Du solltest zuerst die Videomodes erfragen und dann den Videomode setzen. Nicht andersherum. Oder setzt die Groesse einfach, ohne zu fragen.



  • knivil schrieb:

    Du solltest zuerst die Videomodes erfragen und dann den Videomode setzen. Nicht andersherum. Oder setzt die Groesse einfach, ohne zu fragen.

    Ich habe es mittlerweile gelöst. Komischerweise ist es genau das gegenteil Es gibt immer Segementation Fault aus der VideoMode nach dem modi gemacht wird..
    kp wiso
    Ich habe aber noch ein Problem!
    Hier ist erstmal der Funktionierende Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL/SDL.h>
    #include "SDL/SDL_ttf.h" 
    
    int main(){
    
    	char punkte[100];
    	char versuche[3]; // 3 stellen
    	int score;
    	int i, j, k, tcX, tcY;
    	int auflosungX = 1920;
    	int auflosungY = 1080;
    	int pongX, pongY;
    	int speed =  ( auflosungY /128 );
    
    	SDL_INIT_VIDEO;
    	Uint8 *keys;
    	keys = SDL_GetKeyState(NULL);
    	SDL_Event event;
    
    	SDL_Rect player, pong[50], textpos, trytextpos, target[11][5], **modi;
    	SDL_Surface *screen, *text, *tryrect;
    	screen = SDL_SetVideoMode (auflosungX, auflosungY, 16, SDL_HWSURFACE | SDL_NOFRAME);
    
    	modi = SDL_ListModes (NULL, SDL_HWSURFACE|SDL_FULLSCREEN);;
    	auflosungX = modi[0] -> w;
    	auflosungY = modi[0] -> h;
    
    	TTF_Init();
    	SDL_Color color = { 255, 255, 255 }; //Weißer Text
    	TTF_Font *font=TTF_OpenFont("arial.otf", 150);
    	while(1)
    	{
    		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); // HintergrundFarbe
    		int allesvoll = 0;
    		int vorscore = 0; 
    		int XSpeed = auflosungX /500;
    		int YSpeed = auflosungY / 500;
    		anfang:; // für den unwahrscheinlichen fall das irgendjemand den ersten block schafft
    		char try = 3;
    		int vortry = 3;
    		allesvoll = 0;
    
    		pongX = rand() % (( auflosungX/ 2) - (auflosungX / 150)) *2;
    		pongY = rand() % (( auflosungY - (( ( auflosungY -10 ) / 3) * 2 )) + 15);
    
    		player.x = ( auflosungX / 2 ) - ( ( auflosungX / 6.5 ) / 2 );
    		player.y = ( auflosungY / 10 ) * 9;
    		player.h = 10;
    		player.w = ( auflosungX / 6 ) ;
    
    		pong[0].x = pongX;
    		pong[0].y = pongY;
    		pong[0].w = ( auflosungX / 100 );
    		pong[0].h = ( auflosungX / 100 );
    
    		target[0][0].x = auflosungX/ 4;
    		target[0][0].y = auflosungX /5;
    		target[0][0].h = auflosungX / 40;
    		target[0][0].w = ((auflosungX / 50 )* 2);
    
    		for ( tcX = 1; tcX <= 10; tcX ++)
    		{
    			for ( tcY = 0; tcY <= 4; tcY ++)
    			{
    			target[tcX][tcY].x = target[0][0].x + ((target[0][0].w + 1) * tcX);
    			target[tcX][tcY].y = target[0][0].y + ( (target[0][0].h + 1) * tcY);
    			target[tcX][tcY].h = target[0][0].h;
    			target[tcX][tcY].w = target[0][0].w;
    			SDL_FillRect(screen, &target[tcX][tcY], SDL_MapRGB(screen->format, 255, 255, 255));
    
    			}	
    		}
    		textpos.x = auflosungX / 38;
    		textpos.y = auflosungY / 21;
    
    		trytextpos.x = auflosungX - 160;
    		trytextpos.y = textpos.y;
    
    		while (try != 0) 
    		{
    
    			if (try != vortry)
    			{
    				try = vortry;
    				SDL_FillRect(screen, &trytextpos, SDL_MapRGB(screen->format, 0, 0, 0));
    			}
    			SDL_ShowCursor(0); // keinen Curser anzeigen
    			SDL_FillRect(screen, &player, SDL_MapRGB(screen->format, 0, 0, 0)); // hintergrundfarbe
    
    			for ( i = 0; i < speed; i++) // PONGBEWEGUNG
    			{
    				if ( pong[0].x <= 0 )
    				{
    					XSpeed = -XSpeed;
    				}
    				if ( pong[0].x + pong[0].w >= auflosungX)
    				{
    					XSpeed = -XSpeed;
    				}
    				if ( pong[0].y <= 0 )
    				{
    					YSpeed = -YSpeed ;
    				}
    				if ( pong[0].y + pong[0].h >= auflosungY)
    				{	
    					sleep(1);
    					vortry--;
    					YSpeed = -YSpeed ;
    				}
    
    				pong[0].x = pong[0].x + XSpeed;
    				pong[0].y = pong[0].y + YSpeed;
    				for ( j = 49; j > 0; j--) // schweif
    				{
    					pong[j].x = pong[j-1].x;
    					pong[j].y = pong[j-1].y;
    					pong[j].h = pong[j-1].h;
    					pong[j].w = pong[j-1].w;
    					SDL_FillRect(screen, &pong[j], SDL_MapRGB(screen->format, 255 - ((j *5) + 1), 255 -  ((j *5) + 1) , 255  - ((j *5) + 1))); // Farbe für den Pongschweif
    					if ( j == 49)
    					{
    						SDL_FillRect(screen, &pong[j], SDL_MapRGB(screen->format, 0,0,0)); // Farbe für den Pongschweif
    					}
    				}
    
    				if( pong[0].x + pong[0].w >= player.x && pong[0].x <= player.x + player.w) // Schlägerberührung??
    				{
    					if (pong[0].y + pong[0].h >= player.y) // gleich dem schläger
    					{
    						if (pong[0].y + pong[0].h <= player.y + (YSpeed * 2)) // gleich dem schläger
    						{
    							YSpeed = -YSpeed;
    							if ( SDL_MOUSEMOTION && event.motion.xrel /10 != 0) 
    							{
    								XSpeed = ( XSpeed + event.motion.xrel ) / 10;	
    							}
    						}
    					}
    				}
    					for ( tcX = 1; tcX <= 10; tcX ++)
    				{
    					for ( tcY = 0; tcY <= 4; tcY ++)
    					{
    
    						target[tcX][tcY].h = target[0][0].h;
    						target[tcX][tcY].w = target[0][0].w;
    						SDL_FillRect(screen, &target[tcX][tcY], SDL_MapRGB(screen->format, 255, 255, 255));
    
    						if ( pong[0].x >= target[tcX][tcY].x && pong[0].x <= target[tcX][tcY].x + target[tcX][tcY].w)
    						{
    							if ( pong[0].y >= target[tcX][tcY].y && pong[0].y <= target[tcX][tcY].y + target[tcX][tcY].h)
    							{
    							target[tcX][tcY].h = 0;
    							target[tcX][tcY].x = auflosungX; // weg vom screen
    							target[tcX][tcY].y = auflosungY; // weg vom screen
    							SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); // HintergrundFarbe
    							vorscore = vorscore + 100;
    							}
    						}
    						if ( target[tcX][tcY].h == 0)
    						{
    							allesvoll++;
    						}
    					}
    				}
    				allesvoll++;
    				if ( allesvoll > 50)
    				{
    					goto anfang;
    				}
    				allesvoll = 0;
    			}
    
    			if ( SDL_MOUSEMOTION ) 
    			{
    				if (  ( ( event.motion.x + player.w ) > auflosungX ) )
    				{
    					player.x = auflosungX - player.w;
    				}
    				else
    				{
    					player.x = event.motion.x;
    				}
    			}
    			if ( XSpeed >= 7 )	
    			{
    				XSpeed = 7;
    			}
    			if ( XSpeed <= -7 )
    			{
    				XSpeed = -7;
    			}
    			if (  vorscore != score ) 
    			{
    				SDL_FillRect(screen, &textpos, SDL_MapRGB(screen->format, 0, 0, 0));
    				score = vorscore;
    			}
    
    			sprintf(versuche,"%i", try); // score in int umwandeln
    			tryrect = TTF_RenderText_Solid(font, versuche, color);
    			SDL_BlitSurface(tryrect,NULL,screen,&trytextpos);
    
    			sprintf(punkte,"%i", score); // score in int umwandeln
    			text = TTF_RenderText_Solid(font, punkte, color);
    			SDL_BlitSurface(text,NULL,screen,&textpos);
    
    			SDL_FillRect(screen, &player, SDL_MapRGB(screen->format, 255, 255, 255));
    
    			SDL_UpdateRect(screen, 0, 0, 0, 0);
    			while ( SDL_PollEvent(&event) )
    			{
    				switch( event.type )
    				{
    					case SDL_QUIT:
    					break;
    				}
    
    				if ( keys[SDLK_q] )
    				{
    					printf("Ende Durch Abbruch!\n");
    					exit(1);
    				}
    				if ( keys[SDLK_r] )
    				{
    					vortry = 0;
    				}
    			}
    		}
    	}
    }
    

    Der Pongball bewegt sich auf Unterschiedlichen Computern unterschiedlich schnell...
    Das ist schlecht.
    Wie kann ich die Variable speed an die Computergeschwindigkeit anpassen??



  • Ah ja das ist so, weil der Computer dein Programm so schnell ausführt wie er kann, und PCs sind ja unterschiedlich schnell, aber genug Theorie,
    Fakt ist: du musst
    a) ein Framerate Limit setzen (das Programm immer warten lassen wenns zu schnell ausgeführt wird)
    b) die Geschwindigkeit der Objekte immer mit der Zeit seit dem letzten Frame multiplizieren (auch delta time genannt). Also z.B.

    position.x += horizontal_speed; // schlecht
    position.x += horizontal_speed*delta_time; // gut
    

    Allerdings Funktioniert der zweite Ansatz nur wenn die Variablen für Position floats oder doubles sind, denn sonst wird sich garnichts bewegen, weil das ergebnis einer solchen multiplikation immer 0 wäre (es sei denn dein fps ist sehr sehr sehr niedrig, wovon ich nicht ausgehe).

    Es gibt für beides 2 exzellente tutorials von Lazyfoo hier:
    http://lazyfoo.net/SDL_tutorials/lesson32/index.php
    http://lazyfoo.net/SDL_tutorials/lesson14/index.php

    Eine Frage noch: warum hast du alles in die main Funktion gepackt?



  • c0ff33.alex schrieb:

    Eine Frage noch: warum hast du alles in die main Funktion gepackt?

    Ist das schlecht? Wie hättest du es denn gemacht?



  • elmendir schrieb:

    knivil schrieb:

    Du solltest zuerst die Videomodes erfragen und dann den Videomode setzen. Nicht andersherum. Oder setzt die Groesse einfach, ohne zu fragen.

    Ich habe es mittlerweile gelöst. Komischerweise ist es genau das gegenteil

    int main(){
    	int auflosungX = 1920;
    	int auflosungY = 1080;
    
    	screen = SDL_SetVideoMode (auflosungX, auflosungY, 16, SDL_HWSURFACE | SDL_NOFRAME);
    
    	modi = SDL_ListModes (NULL, SDL_HWSURFACE|SDL_FULLSCREEN); // ueberfluessig
    }
    

    Nein, du hast dich nur fuer meinen zweiten Vorschlag entschieden. Wo ist wohl der Unterschied zu:

    int main(){ 
        int auflosungX; // nicht
        int auflosungY; // initialisiert
        screen=SDL_SetVideoMode (auflosungX, auflosungY, 16, SDL_HWSURFACE | SDL_NOFRAME | SDL_DOUBLEBUF); // nicht initialisierte variablen werden verwendet
    


  • Ist das schlecht?

    Also übersichtlich ist es jedenfalls nicht. Keine ahnung ob du das schlecht findest oder nicht.

    Wie hättest du es denn gemacht?

    Ich hätte den Code in mehrere Funktionen und Klassen (bzw. structs) aufgeteilt.


Anmelden zum Antworten