2017-04-05 5 views
0

次のプログラムは、SDL_GetRendererInfoが(関数RenderInit()で)呼び出され、SDL_GetErrorが何かを行う前に動作を停止するまで実行されます。 global_rendererをnullのSDL_Rendererポインタに置き換えてもクラッシュは発生せず、予想されるsdlエラーが発生します。SDL_GetRendererInfoクラッシュ

#include <iostream> 
#include <list> 
#include "SDL.h" 
using namespace std; 
//global variables: 
bool run = true; // whether or not the program should be running 

int global_window_width = 50; //width of window in tiles 

int global_window_height = 35; //height of window in tiles 

SDL_Window* global_window = NULL; //points to primary window 

SDL_Renderer* global_renderer = NULL; //points to renderer for main window 

SDL_RendererInfo* global_renderer_info = NULL; //points to info about above renderer once it's initialized 

SDL_Texture* spritesheet = NULL; //holds the spritesheet 

SDL_Event event; //for holding currently in-handling event 

//function declarations: 
int init(); //initialize SDL 

int windowInit(); //initialize window 

int renderInit(); //create renderers 

int viewInit(); //manages all window, rendering, etc stuff 

int loadSpritesheet(); //loads spritesheet 

void cleanup(); //free up memory, etc 

void dispatchEvent(); //main event handling 

//function definitions: 
int init() 
{ 
    if (SDL_Init(SDL_INIT_EVERYTHING) !=0) 
    { 
     cout << "could not initialize SDL. " << SDL_GetError(); 
     return 1; 
    } 

    return 0; 
} 

int windowInit() 
{ 
    global_window = SDL_CreateWindow("roguelike", 
            SDL_WINDOWPOS_UNDEFINED, 
            SDL_WINDOWPOS_UNDEFINED, 
            global_window_width * 10, 
            global_window_height * 10, 
            SDL_WINDOW_SHOWN); 
    if(global_window == NULL) 
    { 
     cout << "could create window. " << SDL_GetError(); 
     return 1; 
    } 
    return 0; 
} 

int renderInit() 
{ 
     global_renderer = SDL_CreateRenderer(global_window, 
              -1, 
              SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED); 
     if (global_renderer == NULL) 
     { 
      cout << "could not create renderer" << SDL_GetError(); 
      return 1; 
     } 
     SDL_SetRenderDrawColor(global_renderer,0xFF,0xFF,0xFF,0xFF); 
     if (SDL_GetRendererInfo(global_renderer, global_renderer_info) != 0) 
     { 
      cout << "could not get renderer info" << SDL_GetError(); 
      return 1; 
     } 

     return 0; 
} 

int viewInit() 
{ 
    if (windowInit() == 1) 
    { 
     return 1; 
    } 
    else if(renderInit() == 1) 
    { 
     return 1; 
    } 
    else if(loadSpritesheet() == 1) 
    { 
     return 1; 
    } 
    return 0; 
} 

int loadSpritesheet() 
{ 
    SDL_Surface* tempsurf = NULL; //using surface to get image initially, but since surfaces use cpu rendering we switch to textures immediately 

    tempsurf = SDL_LoadBMP("spritesheet.bmp"); //puts image in the surface 

    if (tempsurf == NULL) 
    { 
     cout << "failed to load spritesheet"; 
     SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore 
     return 1; 
    } 
    spritesheet = SDL_CreateTextureFromSurface(global_renderer, tempsurf); 
    if (spritesheet == NULL) 
    { 
     cout << "failed to create spritesheet texture"; 
     SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore 
     return 1; 
    } 
    SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore 
    return 0; 
} 

void cleanup() 
{ 
    SDL_DestroyWindow(global_window); 
    global_window = NULL; 
    SDL_DestroyRenderer(global_renderer); 
    global_renderer = NULL; 
    SDL_DestroyTexture(spritesheet); 
    spritesheet = NULL; 
    global_renderer_info = NULL; 
    SDL_Quit(); 
} 

void dispatchEvent() 
{ 
    SDL_PollEvent(&event); //stores current event information 
    switch(event.type) 
    { 
     case SDL_QUIT: 
     { 
      run = false; 
      break; 
     } 
    } 
} 
//classes: 

class Layer // each layer holds visuals for a certain subset of what is to be displayed; environment, HUD, menu, etc. 
{ 
    Layer(){}; 
}; 

class Camera //renders environment, ui, etc in a series of layers 
{ 
     int width, height; //in tiles 
     SDL_Texture* texture_draw; //texture the camera draws to and sends to be displayed 
     list<Layer*> layer_list; //list of layers to be rendered, back --> front 
    public: 
     Camera(int x, int y, SDL_Renderer* renderer): width(x), height(y) //(width, height, renderer for camera to use) 
     { 
      texture_draw = SDL_CreateTexture(global_renderer,global_renderer_info->texture_formats[0] , SDL_TEXTUREACCESS_TARGET, 10*width, 10*height); 
     }; 
}; 

//main loop 
int main(int argc, char *argv[]) //main function, needed by SDL 
{ 
    if(init() == 0) 
    { 
     if(viewInit() == 0) 
     { 
      while(run) 
      { 
       dispatchEvent(); 

      } 
     } 
    } 
    cleanup(); 
    return 0; 
} 
+2

デバッガを使用すると、問題を見つけやすくなります。 – 1201ProgramAlarm

+0

かもしれません。残念ながら、私はデバッガの経験がありません。 – Lutrin

+2

それは学ぶ良い機会です。デバッグは、すべてのプログラマが実行できる必要があるものです。 – 1201ProgramAlarm

答えて

0

あなたはNULLである、に場所にglobal_renderer_infoポイントをレンダラ情報を書き込むためにSDL_GetRendererInfoを求めています。 NULLに書き込むとセグメント化エラーが発生します。これは予想される動作です。

正しいコードは、(好ましくは、スタックまたはグローバルエリア内)レンダラ情報のためのメモリを割り当て、その場所に書き込む必要があり、例えば:で修正

SDL_RendererInfo info = {0}; 
SDL_GetRendererInfo(global_renderer, &info); 
// ... use info fields 
0

:代わりにポインタとしてglobal_renderer_info宣言するSDL_RendererInfoに、代わりにオブジェクトを直接宣言し、それに応じてコードの残りの部分を変更しました。