2017-04-04 3 views
0

키보드 입력을 기반으로 상자를 이동하는 프로그램을 만들려고하고 있지만 화면에 녹색 사각형 만 렌더링하도록 설정되어 있습니다. 그러나 프로그램이 창을 초기화 한 다음 종료하기 전에 "분할 오류 (코어 덤프)"이상을 반환하지 않는 것 같습니다. 컴파일러 오류가 전혀 발생하지 않으며 코드의 상당 부분이 온라인에서 찾은 자습서와 일치합니다. 차이가 있다면 GCC를 사용하여 우분투에서 Code :: Blocks를 실행합니다.SDL2 세그멘테이션 오류

main 기본적으로, initdrawRect라는 함수를 호출하고, close가 순서대로 (모든 아래 그림 참조), 성공 또는 실패에 따라 인쇄 문.

편집 : 아래 표시된대로 close으로 범위를 좁 힙니다. 특히, 그것은 문제를주는 SDL_FreeSurface 및 SDL_Quit입니다. 또한 포인터 처리와 관련하여 close (및 프로그램의 다른 부분)를 정리하고 새로운 pastebin 파일을 만들었습니다.

가까운 :

여기
void close() 
{ 
    // Deallocate gScreenSurface 
    SDL_FreeSurface(gScreenSurface); 
    gScreenSurface=NULL; 

    // Destroy renderer 
    SDL_DestroyRenderer(gRenderer); 
    gRenderer=NULL; 

    // Destroy gWindow 
    SDL_DestroyWindow(gWindow); 
    gWindow=NULL; 

    SDL_Quit(); 
} 

는, 포인터의 초기화와 완료 새로운 전체 소스 코드,의 포함과 의사 :

/* === Includes === */ 
#include <cstdlib> 
#include <stdio.h> 
#include "SDL2/SDL.h" 

using namespace std; 

/* === Constants === */ 
const int SCREEN_WIDTH = 640; 
const int SCREEN_HEIGHT = 480; 

/* === Enums === */ 
/*enum Keys {KEY_DEFAULT, 
      KEY_UP, 
      KEY_DOWN, 
      KEY_LEFT, 
      KEY_RIGHT, 
      KEY_TOTAL};*/ 

/* === Prototypes === */ 

bool init(); 
bool drawRect(SDL_Renderer* pRenderer, SDL_Rect* pRect, int pX, int pY, int pW, int pH, int pR, int pG, int pB, int pA); 
void close(); 

/* === Pointer Initialization === */ 
SDL_Window* gWindow = NULL; 
SDL_Surface* gScreenSurface = NULL; 
SDL_Renderer* gRenderer = NULL; 
SDL_Rect* gRect = NULL; 

/**================================================== 
Box Mover 

This was intended to be a learning activity to 
teach myself how to use SDL, in particular basic 
"block" graphics and keyboard inputs. 

Unfortunately, I can't figure out why it's always 
returning seg fault. I think it's outside of main, 
but I can't be sure. 
==================================================**/ 

int main() 
{ 
    if(!init()) 
     printf("Failed to initialize!\n"); 
    else 
    { 
     if(!drawRect(gRenderer, gRect, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 255, 0, 255)) 
     printf("Failed to draw rectangle!\n"); 
     else 
     { 
     /*SDL_BlitSurface(gImage, NULL, gScreenSurface, NULL); 
     SDL_UpdateWindowSurface(gWindow); 
     SDL_Delay(2000);*/ 
     printf("Success in main!\n"); // Placeholder until I figure out why I'm getting a seg fault, then I can fix the contents. 
     } 
    } 
    close(); 

    return 0; 
} 

/*========================= 
Init 

Initializes SDL 
Returns true for success, false for failure 
Prints error on failure 
=========================*/ 
bool init() 
{ 
    //Initialization flag 
    bool success = true; 
    if(SDL_Init(SDL_INIT_VIDEO) < 0) 
    { 
     printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); 
     success = false; 
    } 
    else 
    { 
     gWindow = SDL_CreateWindow("Box Mover", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); 
     if(gWindow == NULL) 
     { 
     printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); 
     success = false; 
     } 
     else 
     { 
     gScreenSurface = SDL_GetWindowSurface(gWindow); 
     } 
    } 
    return success; 
} 

/*========================= 
Draw Rectangle 

Draws a rectangle of specified color and location 

TO DO: 
Check to see if renderer needs to be deallocated here. 

Inputs: 
>> pRenderer:  SDL_Renderer pointer which can be thought of as a drawing tool 
>> pRect:   SDL_Rect pointer which holds location and size data 
>> pX, pY:  X-Y location of the upper left corner of the rectangle 
>> pR, pG, pB: Color values (technically Uint8, 0-255) 
>> pA:   Alpha (transparency) value of the rectangle (also technically Uint8) 
=========================*/ 
bool drawRect(SDL_Renderer* pRenderer, SDL_Rect* pRect, int x, int y, int w, int h, int r, int g, int b, int a) 
{ 
    bool success = true; 

    pRenderer=SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_SOFTWARE); 
    if(pRenderer==NULL) 
    { 
     printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); 
     success=false; 
    } 
    else 
    { 
     pRect = new SDL_Rect; 
     if(pRect == NULL) 
     { 
     printf("Could not create rectangle! SDL Error: %s\n", SDL_GetError()); 
     success=false; 
     } 
     else 
     { 
      pRect->x = x; 
      pRect->y = y; 
      pRect->w = w; 
      pRect->h = h; 

     SDL_SetRenderDrawColor(pRenderer, r, g, b, a); 

     if(SDL_RenderDrawRect(pRenderer, pRect) < 0) 
     { 
      printf("Rectangle could not be rendered! SDL Error: %s\n", SDL_GetError()); 
      success=false; 
     } 
     } 
    } 
    return success; 
} 

/*========================= 
Close 

Closes the SDL systems cleanly, deallocating memory. 

Found the seg fault! It's this fucker! 
In particular, SDL_FreeSurface and SDL_Quit 
=========================*/ 
void close() 
{ 
    // Deallocate gScreenSurface 
    SDL_FreeSurface(gScreenSurface); 
    gScreenSurface=NULL; 
    printf("Surface closed. Working on renderer...\n"); 

    // Destroy renderer 
    SDL_DestroyRenderer(gRenderer); 
    gRenderer=NULL; 
    printf("Renderer closed. Working on window...\n"); 

    // Destroy gWindow 
    SDL_DestroyWindow(gWindow); 
    gWindow=NULL; 
    printf("Window closed. Working on SDL...\n"); 

    SDL_Quit(); 
    printf("SDL closed.\n"); 
} 
+4

추가 경고 기능이 활성화되어 있으면 빌드하고 오류가 있으면 수정하십시오. 그리고 디버그 정보로 빌드하고, 디버거에서 실행하여 작동중인 크래시를 잡아 발생하는 위치를 찾습니다. –

+0

너 평생 동안 RAII가 필요해. – jaggedSpire

+0

먼저이 예제를 테스트 했습니까? https://wiki.libsdl.org/SDL_CreateWindow – Rama

답변

1

당신하여 drawRect 함수에 SDL_Renderer *renderer 포인터를 전달하는 값을 만들고 그 함수에서 초기화합니다. 그것은 전역 범위에있는 포인터를 초기화하지 않습니다. 함수를 종료 할 때 잃어버린 복사본을 초기화합니다. 그런 다음 close에 있으며 NULL 인 전역 범위의 포인터에서 SDL_DestroyRenderer을 호출합니다.

drawRect 함수 내에서 전역 변수를 초기화하려면 포인터에 대한 포인터 (SDL_Renderer **)를 함수에 전달해야합니다. 당신이 SDL_RenderDrawRect를 호출하고 당신의 drawRect 기능에

,이 다음

+0

이것은 아마도 내 문제의 일부일 것입니다. 불행히도, 나는 더 많은 것을 가지고 있습니다. (나의 삶의 이야기 tbh.) –

0

이 무료하지 마십시오 SDL_RenderPresent에 전화를 사용할 필요가 화면에 그릴, 백 버퍼에 사각형을 렌더링하고

gScreenSurface = SDL_GetWindowSurface(gWindow); 
... 
SDL_FreeSurface(gScreenSurface); 

SDL_GetWindowSurface() (강조 광산)의 문서를 참조하십시오 :

01 SDL_GetWindowSurface()에서 반환 된 표면은 SDL은 반환 된 포인터 자체의 수명을 관리한다

비고

필요한 경우, 새로운 표면이 최적의 형식으로 작성됩니다. 이 표면은 창을 없애면 해제됩니다. 이 표면을 비우지 마십시오.