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
Alexdanke!
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.phpEine 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.