2016-11-08 1 views
1

Je le code SDL simple:segfault étrange de SDL_FreeSurface

#include <SDL.h> 
#include <stdbool.h> 
#include <stdio.h> 

// helpers 

bool init(SDL_Window **win, SDL_Surface **surf) { 
     int const width = 800; 
     int const height = 600; 
     if (SDL_Init(SDL_INIT_VIDEO) != 0) { 
       fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); 
       return false; 
     } 
     *win = SDL_CreateWindow("Picture test", 
           SDL_WINDOWPOS_CENTERED, 
           SDL_WINDOWPOS_CENTERED, 
           width, height, 0); 
     if (*win == NULL) { 
       fprintf(stderr, 
         "Unable to create window: %s\n", 
         SDL_GetError()); 
       return false; 
     } 
     *surf = SDL_GetWindowSurface(*win); 
     return true; 
} 

bool load_media(SDL_Surface **surf) { 
     *surf = SDL_LoadBMP("./sample.bmp"); 
     if (*surf == NULL) { 
       fprintf(stderr, "Unable to load data: %s\n", SDL_GetError()); 
       return false; 
     } 
     return true; 
} 

void close(SDL_Window **win, SDL_Surface **surf) { 
     SDL_FreeSurface(*surf); 
     SDL_DestroyWindow(*win); 
     SDL_Quit(); 
} 


int main() 
{ 
     SDL_Window *win; 
     SDL_Surface *surf; 
     SDL_Surface *img; 
     if (!init(&win, &surf)) { 
       return EXIT_FAILURE; 
     } 
     if (!load_media(&img)) { 
       return EXIT_FAILURE; 
     } 
     SDL_BlitSurface(img, NULL, surf, NULL); 
     SDL_UpdateWindowSurface(win); 
     SDL_Delay(2000); 
     close(&win, &img); 
} 

Mon code segfaults toujours close (l'origine du segfault selon GDB est la ligne SDL_FreeSurface(*surf)). Plus étrangement, si je remplace l'appel à close par sa définition, cela se sépare toujours exactement au même endroit. Plus précisément, si je remplace close(&win, &img) avec:

SDL_FreeSurface(img); 
SDL_DestroyWindow(win); 
SDL_Quit(); 

le code encore segfaults exactement au même endroit, même si cette fonction est même pas appelé. Ce n'est que si je supprime la totalité de la fonction close que cela fonctionne correctement. Je suis complètement confus quant à ce qui pourrait causer cela.

+0

Vous savez qu'il existe une fonction de bibliothèque C 'int close (int fd);'? Y a-t-il des conflits - avertissements du compilateur? –

+0

@WeatherVane J'ai essayé de renommer '' close'' pour quelque chose d'autre, et ça l'a corrigé! Étonnamment, malgré tous les avertissements imaginables, le compilateur l'a encore accepté! –

+1

@KozRoss de plus il peut être accepté sans aucun avertissement, puisque dans la glibc 'close' (et beaucoup d'autres) est un symbole faible. Avec ce genre de noms simples (et une portée limitée), il peut être raisonnable d'utiliser des fonctions 'static'. – keltar

Répondre

5

S'il vous plaît Renommez votre fonction

void close(SDL_Window **win, SDL_Surface **surf) 

depuis close est une fonction de la bibliothèque standard C.

2

Je peux le confirmer. Même scénario Même avec -Wall et -Wextra le compilateur n'a pas craché d'avertissement de redéclaration. Idem pour open().

J'ai besoin de l'avis d'un expert si c'est un bug de gcc.

  • Solution 1: déclarer votre close() comme une fonction statique (par exemple static close()).
  • Solution 2: renommez la fonction close() en autre chose (par exemple, my_close_foo()).
+0

Je * espère * que c'est un bug - ce serait vraiment effrayant si GCC ne vous avertissait pas au moins de quelque chose d'aussi ridicule. Idem pour Clang. –