2016-11-08 2 views
1

У меня есть следующий простой SDL код:Strange из 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); 
} 

Мой код всегда на close ошибку сегментации (происхождение Segfault по GDB является линия SDL_FreeSurface(*surf)). Более странно, если я заменил вызов на close с его определением, это все равно останется в одном месте. В частности, если я заменю close(&win, &img) с:

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

Кодекса все еще точно ошибки сегментации в том же месте, даже если эта функция даже не вызывается. Только если я удалю всю функцию close, это работает правильно. Я совершенно смущен тем, что может быть причиной этого.

+0

Вы знаете, что существует функция библиотеки C 'int close (int fd);'? Есть ли предупреждения о конфликтах - компиляторах? –

+0

@WeatherVane Я попытался переименовать '' close'' в что-то еще, и это исправило это! Удивительно, но, несмотря на все мыслимые предупреждения, компилятор все равно принял это! –

+1

@ KozRoss кроме того, он может быть принят без предупреждения, поскольку в glibc 'close' (и многие другие) является слабым символом. С такими простыми именами (и ограниченной областью) было бы разумно использовать 'static' функции. – keltar

ответ

5

Пожалуйста, переименуйте вашу функцию

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

так close стандартная функция библиотеки C.

2

Могу подтвердить это. Тот же сценарий. Даже с -Wall и -Wextra компилятор не выплюнул предупреждение о повторной регистрации. То же самое для open().

Мне нужно мнение экспертов, если это ошибка gcc.

  • Решение 1: объявить close() как статическая функция (например, static close()).
  • Решение 2: переименуйте функцию close() на что-то другое (например, my_close_foo()).
+0

Я * надеюсь, что это ошибка - было бы очень страшно, если бы GCC нисколько не предупредил вас о чем-то, что явно глупо. То же самое касается Клана. –

Смежные вопросы