2016-04-07 11 views
0

SDL_ttf'yi yakın zamanda yazdığım bir parçacık jeneratörü programına entegre etmeye çalışıyorum, ancak bir çalışma zamanı hatası almaya devam ediyorum: Access violation reading location 0x00000044.. Bu, oyun ekranına bir metin yüzeyini karıştırmaya çalıştığımda ortaya çıkar. Kodumu kullanarak birkaç kez taradım ve geçmişte benzer sorunlar yaşadım, ancak sorunu anlayamıyorum. Muhtemelen problem nedir?Neden SDL2_ttf ile Metin Karıştığında Erişim İhlal Hatası Alabilirim?

hata Text.h oluşur:

#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: ayıklayıcısında

#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' kullanarak' text' oluşturulduktan sonra 'text' ... 'yaparak' text' başarılı bir şekilde oluşturulup oluşturulmadığını kontrol etmelisiniz. "TTF_RenderText_Solid", oluşturma başarısız olursa "null" değerini döndürecek ve erişim ihlali açıklanacaktır: denediğim null – Chara

+0

@Chara'dan okumaya çalışıyorum; "SDL_BlitSurface" işlev çağrılarının yanı sıra, durumunun değiştirilmiş olabileceği her yerde "metnin" geçerliliğini kontrol ettim. Istisna hala aynı çağrı tarafından atılır. Sorun olabilecek başka bir şey biliyor musunuz? – CornOnTheMacabre

cevap

0

Çalışma uygulama ve kırılmaya istisna. Çağrı yığınını kontrol edin. Şansınız varsa, istisnanın meydana geldiği yerde kendi kodunuzda yakalar. Kural dışı durum kod modülünüzde bulunmuyorsa, arayanın argümanlarını inceleyebileceğiniz kod kısmına ulaşıncaya kadar arama yığınınızı (orada sunulan listeden aşağıya) tıklayın. Bu noktada yanlış gittiği yer. 0x44 şüphesiz ASCII '$' gibi, txt'inizde $ var mı?

+0

evet, çağrı yığınına baktım ve istisnanın nerede atıldığını buldum; Text :: DrawText() (yukarıdaki kod snippetindeki çağrıyı etiketledim) SDL_BlitSurface() çağrısıydı. Ve hayır, oluşturmaya çalıştığım tek metin, bir Bar nesnesinin 8 bitlik renk değerini temsil edecek sayılardır. – CornOnTheMacabre

İlgili konular