私は最近作成したパーティクルジェネレータプログラムに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);
}
'TTF_RenderText_Solid'を使って' text'を作成した後、 'if(text)...'を実行して 'text'が正常に作成されたかどうか確認する必要があります。 'TTF_RenderText_Solid'は、作成が失敗した場合に' null'を返し、それはアクセス違反を説明します:nullから読み込もうとしています。 – Chara
@Chara試しました。 SDL_BlitSurfaceへの関数呼び出しの前に、状態が変更されている可能性のあるどこでも 'text'の有効性を確認しました。例外は、同じ呼び出しによってスローされます。あなたは他に何か問題があると知っていますか? – CornOnTheMacabre