2017-05-07 220 views
0

我試圖在中呈現文本。該文本應出現在剪輯區域SDL_Rect rcTextOutput中的SDL_Rect destination中,但它會返回錯誤。我試圖用進行調試,但我仍然沒有看到問題。拋出異常返回內存異常錯誤

我會在年底離開整個代碼,但這裏的地方文字獲取呈現部分:

SDL_SetRenderDrawColor(gRenderer, 0x40, 0x40, 0x40, 0x40); 

gTextSurface = TTF_RenderText_Solid(gFont, "text", gTextColor); 
if (gTextSurface == NULL) 
{ 
    throw "Unable to render texture! ERROR: "; 
} 
gTextTexture = SDL_CreateTextureFromSurface(gRenderer, gTextSurface); 
if (gTextTexture == NULL) 
{ 
    throw "Unable to render texture! ERROR: "; 
} 

SDL_Rect destination; 
destination.x = rcTextOutput.x + rcTextOutput.w - 800; 
destination.y = rcTextOutput.y; 
destination.w = 800; 
destination.h = 20; 

SDL_RenderSetClipRect(gRenderer, &rcTextOutput); 
SDL_RenderCopy(gRenderer, gTextTexture, NULL, &destination); 
SDL_RenderSetClipRect(gRenderer, NULL); 

// ... 

SDL_RenderPresent(gRenderer); 

我注意到SDL_SetClipRect()this answer及其例子,但它不工作。

我已經看過這個Lazy Foo' tutorial,代碼似乎是按順序。我也運行在它和它返回:

Starting program: /home/pradana/Projects/sierra/caventure/build/caventure 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/usr/lib/libthread_db.so.1". 
[New Thread 0x7fffeb5f1700 (LWP 25319)] 
[New Thread 0x7fffeadf0700 (LWP 25320)] 
terminate called after throwing an instance of 'char const*' 

Thread 1 "caventure" received signal SIGABRT, Aborted. 
0x00007ffff6c92a10 in raise() from /usr/lib/libc.so.6 

我甚至嘗試

==25239== Memcheck, a memory error detector 
==25239== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==25239== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info 
==25239== Command: build/./caventure 
==25239== 
==25239== Syscall param writev(vector[...]) points to uninitialised byte(s) 
==25239== at 0x5CF218D: ??? (in /usr/lib/libc-2.25.so) 
==25239== by 0x8088BAC: ??? (in /usr/lib/libxcb.so.1.1.0) 
==25239== by 0x8088FAC: ??? (in /usr/lib/libxcb.so.1.1.0) 
==25239== by 0x808902C: xcb_writev (in /usr/lib/libxcb.so.1.1.0) 
==25239== by 0x7D7EF3D: _XSend (in /usr/lib/libX11.so.6.3.0) 
==25239== by 0x7D7F431: _XReply (in /usr/lib/libX11.so.6.3.0) 
==25239== by 0x7D6A2EE: XInternAtom (in /usr/lib/libX11.so.6.3.0) 
==25239== by 0x4EFB79A: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4EFC694: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4EEB87F: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4EEB60E: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4E4F1C6: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== Address 0x79c5573 is 35 bytes inside a block of size 16,384 alloc'd 
==25239== at 0x4C2CF35: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==25239== by 0x7D6F385: XOpenDisplay (in /usr/lib/libX11.so.6.3.0) 
==25239== by 0x4EFA84F: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4EEB5BB: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4E4F1C6: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1) 
==25239== by 0x4011F3: init() (in /home/pradana/Projects/sierra/caventure/build/caventure) 
==25239== by 0x40148A: main (in /home/pradana/Projects/sierra/caventure/build/caventure) 
==25239== 
terminate called after throwing an instance of 'char const*' 
==25239== 
==25239== Process terminating with default action of signal 6 (SIGABRT): dumping core 
==25239== at 0x5C41A10: raise (in /usr/lib/libc-2.25.so) 
==25239== by 0x5C43139: abort (in /usr/lib/libc-2.25.so) 
==25239== by 0x53ED4EC: __gnu_cxx::__verbose_terminate_handler() (vterminate.cc:95) 
==25239== by 0x53EB2A5: __cxxabiv1::__terminate(void (*)()) (eh_terminate.cc:47) 
==25239== by 0x53EB2F0: std::terminate() (eh_terminate.cc:57) 
==25239== by 0x53EB507: __cxa_throw (eh_throw.cc:87) 
==25239== by 0x4013FC: loadMedia() (in /home/pradana/Projects/sierra/caventure/build/caventure) 
==25239== by 0x40148F: main (in /home/pradana/Projects/sierra/caventure/build/caventure) 
==25239== 
==25239== HEAP SUMMARY: 
==25239==  in use at exit: 13,232,031 bytes in 33,989 blocks 
==25239== total heap usage: 76,191 allocs, 42,202 frees, 50,434,525 bytes allocated 
==25239== 
==25239== LEAK SUMMARY: 
==25239== definitely lost: 16 bytes in 1 blocks 
==25239== indirectly lost: 176 bytes in 4 blocks 
==25239==  possibly lost: 4,143,500 bytes in 29,652 blocks 
==25239== still reachable: 9,088,339 bytes in 4,332 blocks 
==25239==   suppressed: 0 bytes in 0 blocks 
==25239== Rerun with --leak-check=full to see details of leaked memory 
==25239== 
==25239== For counts of detected and suppressed errors, rerun with: -v 
==25239== Use --track-origins=yes to see where uninitialised values come from 
==25239== ERROR SUMMARY: 5 errors from 1 contexts (suppressed: 0 from 0) 

這裏的腳本的其餘部分(不相關的代碼被刪除):

#include <stdio.h> 
#include <string> 
#include <SDL2/SDL.h> 
#include <SDL2/SDL_ttf.h> 

// Screen dimensions, constants 
const int SCREEN_WIDTH = 800; 
const int SCREEN_HEIGHT = 900; // 600 for ground, 280 for output, 20 for input 

SDL_Surface* gScreenSurface = NULL; // The surface contained by the window 
SDL_Surface* gCurrentSurface = NULL; // Current displayed image 
SDL_Surface* gTextSurface = NULL; // SDL_Surface for the text. 
SDL_Texture* gTextTexture = NULL; // SDL_Texture for the text. 
TTF_Font* gFont = NULL; // Font pointer. 
SDL_Color gTextColor = { 0, 0, 0, 0xFF }; // Text color, white. 


SDL_Renderer* gRenderer = NULL; // The renderer we'll be using 
SDL_Rect rcGround, rcSprite, rcTextInput, rcTextOutput; 

void init(); 
void loadMedia(); 
void quit(); 

void init() 
{ 
    if (SDL_Init(SDL_INIT_VIDEO) > 0) 
    { 
    throw "SDL failed to initialise! ERROR: "; 
    } 
    else 
    { 
    // CODE REDACTED: gWindow and gRenderer is initialised 
    if (TTF_Init() > 0) 
    { 
     throw "TTF could not be initialised! ERROR: "; 
    } 
    } 
} 

void loadMedia() 
{ 
    // Ground rendering 
    rcGround.x = 0; 
    rcGround.y = 0; 
    rcGround.w = 800; 
    rcGround.h = 600; 

    // Sprite rendering 
    rcSprite.x = 400; 
    rcSprite.y = 300; 
    rcSprite.w = 4; 
    rcSprite.h = 4; 

    // TextOutput box rendering 
    rcTextOutput.x = 0; 
    rcTextOutput.y = 600; 
    rcTextOutput.w = 800; 
    rcTextOutput.h = 280; 

    // TextInput box rendering 
    rcTextInput.x = 0; 
    rcTextInput.y = 880; 
    rcTextInput.w = 800; 
    rcTextInput.h = 20; 

    gFont = TTF_OpenFont("resources/consolas.ttf", 14); 
    if (gFont == NULL) 
    { 
    throw "Font load error"; 
    } 
} 

void quit() 
{ 
    // Destroy window 
    SDL_DestroyWindow(gWindow); 
    SDL_DestroyRenderer(gRenderer); 
    SDL_DestroyTexture(gTextTexture); 
    SDL_FreeSurface(gTextSurface); 
    TTF_CloseFont(gFont); 
    gWindow = NULL; 
    gRenderer = NULL; 
    gFont = NULL; 

    // Quit SDL subsystems 
    TTF_Quit(); 
    SDL_Quit(); 
} 

int main() 
{ 
    try 
    { 
    init(); 
    loadMedia(); 

    bool quit = false; 
    SDL_Event event; 

    while(!quit) 
    { 
     // CODE REDACTED: event & sprite movement 
     } 
     if (rcSprite.x < 0 || rcSprite.y < 0 || rcSprite.y > rcGround.h || rcSprite.x > rcGround.w) 
     { 
     rcSprite.x = 400; 
     rcSprite.y = 300; 
     } 

     SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0x00, 0x00); 
     SDL_RenderClear(gRenderer); 

     SDL_RenderFillRect(gRenderer, &rcGround); 
     SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcGround); 

     SDL_RenderFillRect(gRenderer, &rcTextInput); 
     SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcTextInput); 

     SDL_SetRenderDrawColor(gRenderer, 0x40, 0x40, 0x40, 0x40); 

     gTextSurface = TTF_RenderText_Solid(gFont, "text", gTextColor); 
     if (gTextSurface == NULL) 
     { 
     throw "Unable to render texture! ERROR: "; 
     } 
     gTextTexture = SDL_CreateTextureFromSurface(gRenderer, gTextSurface); 
     if (gTextTexture == NULL) 
     { 
     throw "Unable to render texture! ERROR: "; 
     } 

     SDL_Rect destination; 
     destination.x = rcTextOutput.x + rcTextOutput.w - 800; 
     destination.y = rcTextOutput.y; 
     destination.w = 800; 
     destination.h = 20; 

     SDL_RenderSetClipRect(gRenderer, &rcTextOutput); 
     SDL_RenderCopy(gRenderer, gTextTexture, NULL, &destination); 
     SDL_RenderSetClipRect(gRenderer, NULL); 

     SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 

     SDL_RenderDrawLine(gRenderer, 0, 600, 800, 600); 
     SDL_RenderDrawLine(gRenderer, 0, 880, 800, 880); 

     SDL_RenderFillRect(gRenderer, &rcSprite); 
     SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcSprite); 

     SDL_RenderPresent(gRenderer); 
    } 
    } 
    catch (const std::string& msg) 
    { 
     printf("%s", msg.c_str()); 
     if (SDL_GetError() != NULL) 
     { 
      printf("%s", SDL_GetError()); 
     } 
    else if (TTF_GetError() != NULL) 
     { 
      printf("%s", TTF_GetError()); 
     } 
    else 
    { 
     printf("%s", "NULL"); 
    } 
    quit(); 
     exit(EXIT_FAILURE); 
    } 
    quit(); 
    return 0; 
} 

回答

2

你拋出一個指向字符數組的指針,但試着去引用::std::string。這顯然不起作用,你的程序因未捕獲的異常而終止。您應該在拋出時顯式構造一個字符串,或者實際上應該拋出並捕獲可包含說明的std::runtime_error實例。

throw(::std::runtime_error("Unable to render texture!")); 
... 
catch(::std::runtime_error const & exception) 
{ 
    printf("%s", exception.what()); 
+0

呵呵。顯然這是問題所在。好吧,謝謝。實際上我發現這個錯誤,'TTF_OpenFont()'的文件路徑是錯誤的,然後它就起作用了。當我運行它時很有趣,'rcTextOutput'變黑,我看不到任何文本。 –