2016-04-07 37 views
0

私は最近作成したパーティクルジェネレータプログラムにSDL_ttfを統合しようとしていますが、ランタイムエラーが発生し続ける:Access violation reading location 0x00000044.これは、テキスト面をゲーム画面にblitしようとしたときに発生します。私は自分のコードを何度かスキャンして、これまでと同様の問題を抱えていましたが、問題を理解することはできません。どのような問題が起こりそうですか?SDL2_ttfでテキストをブリッジするときにアクセス違反エラーが発生するのはなぜですか?

エラーがText.hで発生します。

#pragma once 

#include "System.h" 
#include <iostream> 
#include <sstream> 

class Text { 
public: 
    Text(const char *fontaddress = "times.ttf", int size = 30, const char 
     *begintext = "0", int x = 0, int y = 0, SDL_Color color = { 255, 255, 255 }) { 
     font = TTF_OpenFont(fontaddress, size); 

     drawpos.x = x; 
     drawpos.y = y; 

     textcolor = color; 

     text = TTF_RenderText_Solid(font, begintext, textcolor); 
     if (!text) 
      std::cout << "damn" << std::endl; 
    } 
    ~Text() { 
     if (text) 
      SDL_FreeSurface(text); 
     TTF_CloseFont(font); 
    } 

    void SetText(const char *txt); 
    void SetText(int txt); 
    void DrawText(); 
private: 
    TTF_Font *font; 
    SDL_Rect drawpos; 
    SDL_Color textcolor; 
    SDL_Surface *text; 
}; 

inline void Text::SetText(const char *txt) { 
    if (text) 
     SDL_FreeSurface(text); 

    text = TTF_RenderText_Solid(font, txt, textcolor); 
} 


inline void Text::SetText(int txt) { 
    if (text) 
     SDL_FreeSurface(text); 

    std::stringstream s; 
    s << txt; 
    text = TTF_RenderText_Solid(font, s.str().c_str(), textcolor); 
} 

inline void Text::DrawText() { 
    static SDL_Surface *const screen = System::GetInstance().GetScreen(); 
    SDL_BlitSurface(text, NULL, screen, &drawpos); 
    //^This line throws the exception 
} 

Bar.h:

#pragma once 

#include <SDL.h> 
#include <iostream> 
#include "System.h" 
#include "Text.h" 

class Bar { 
public: 
    Bar(const int xpos = 0, const int ypos = 0, unsigned width = 0, unsigned height = 0, const Uint32 c = SDL_MapRGB(System::GetInstance().GetScreen()- >format, 0, 0, 0), const char *address = "times.ttf", 
     int sz = 30, const char *bgtext = "0", SDL_Color co = { 255, 255, 255 }) : max_w(width), color(c), colortext(address, sz, bgtext, xpos - 50, ypos, co) { 
     bar.x = xpos; 
     bar.y = ypos; 
     bar.w = width; 
     bar.h = height; 

     modval = max_w/255; 
     if (!modval) 
      modval = 1; 
     if (max_w < 255) { 
      std::cerr << "invalid width; below 255" << std::endl; 
     } 
     colorval = width/modval; 
    } 

    void Modify(int width_modifier); 
    void Draw(); 
    Uint8 GetColorVal(); 
private: 
    SDL_Rect bar; 
    unsigned max_w; 
    Uint32 color; 
    Uint8 modval; // number of pixels (in width) required to advance or decrement the color value by 1 
    Uint8 colorval; // the color value modified when width is changed. Determined by 
      // modval. This value will be used by RGBTable class for text (on-screen value display) and particle color creation 
    Text colortext; 
}; 

//inlined methods 

//modifies the width of a bar 
inline void Bar::Modify(int width_modifier) { 
    if (bar.w + width_modifier < 0 || bar.w + width_modifier > max_w) 
     return; 

     bar.w += width_modifier; 
     if (bar.w % modval == 0) { 
      colorval = bar.w/modval; 
      colortext.SetText(colorval); 
     } 
} 


//draws bar to system screen 
inline void Bar::Draw() { 
    static SDL_Surface *screen = System::GetInstance().GetScreen(); 
    SDL_FillRect(screen, &bar, color); 
    colortext.DrawText(); 
} 


//returns the 8bit color value represented by the width of a bar 
inline Uint8 Bar::GetColorVal() { 
    return colorval; 
} 

ColorTable.h:

#pragma once 

#include "System.h" 
#include "Bar.h" 
#include <array> 

class ColorTable { 
public: 
    static bool needupdate; 
    static ColorTable &GetInstance(); 

    void Input(); 
    void Draw(); 
    Uint32 MakeColor(); 
private: 
    ColorTable(int top_left_x, int top_left_y, unsigned width, int height, int sepval) { 
     static SDL_Surface *screen = System::GetInstance().GetScreen(); 

     bars[0] = Bar(top_left_x, top_left_y, width, height, SDL_MapRGB(screen->format, 255, 0, 0)); 
     bars[1] = Bar(top_left_x, top_left_y + height + sepval, width, height, SDL_MapRGB(screen->format, 0, 255, 0)); 
     bars[2] = Bar(top_left_x, top_left_y + (sepval *2) + (height * 2), width, height, SDL_MapRGB(screen->format, 0, 0, 255)); 

     activebar = bars.begin(); 
    } 

    std::array<Bar, 3> bars; 
    std::array<Bar, 3>::iterator activebar; 
    const Uint8 *key = SDL_GetKeyboardState(NULL); 
}; 

inline ColorTable &ColorTable::GetInstance() { 
    static ColorTable table(750, 620, 510, 50, 10); 
    return table; 
} 

inline void ColorTable::Draw() { 
    bars[0].Draw(); 
    bars[1].Draw(); 
    bars[2].Draw(); 
} 

inline Uint32 ColorTable::MakeColor() { 
    static SDL_Surface *screen = System::GetInstance().GetScreen(); 

    Uint8 r = bars[0].GetColorVal(); 
    Uint8 g = bars[1].GetColorVal(); 
    Uint8 b = bars[2].GetColorVal(); 

    return SDL_MapRGB(screen->format, r, g, b); 
} 
+0

'TTF_RenderText_Solid'を使って' text'を作成した後、 'if(text)...'を実行して 'text'が正常に作成されたかどうか確認する必要があります。 'TTF_RenderText_Solid'は、作成が失敗した場合に' null'を返し、それはアクセス違反を説明します:nullから読み込もうとしています。 – Chara

+0

@Chara試しました。 SDL_BlitSurfaceへの関数呼び出しの前に、状態が変更されている可能性のあるどこでも 'text'の有効性を確認しました。例外は、同じ呼び出しによってスローされます。あなたは他に何か問題があると知っていますか? – CornOnTheMacabre

答えて

0

デバッガでアプリケーションを実行し、で破ります例外。コールスタックを検査します。あなたが運が良ければ、例外が発生した場所のコードにトラップします。トラップのコードモジュールに例外がない場合は、呼び出し元の引数を調べるコードの部分に到達するまで、呼び出しスタックを(そこに表示されているリストの下に)クリックします。その時点でそれは間違っていた。 0x44はASCII '$'のように疑わしいですが、あなたのtxtには$がありますか?

+0

ええ、私は呼び出しスタックを見て、どこに例外がスローされたかを見つけました。これはText :: DrawText()のSDL_BlitSurface()への呼び出しでした(上記のコードスニペットで呼び出しをラベル付けしました)。そして、私が作成しようとした唯一のテキストは、Barオブジェクトの8ビットカラー値を表す数字です。 – CornOnTheMacabre

関連する問題