我正在尝试将SDL_ttf集成到我最近编写的粒子生成器程序中,但我不断收到运行时错误:Access violation reading location 0x00000044.
。当我尝试将文本表面blit到游戏屏幕时会发生这种情况。我已经多次扫描过我的代码,并且过去遇到了类似的问题,但我无法弄清楚这个问题。问题最有可能是什么?
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 :(得分:0)
在调试器中运行应用程序并中断异常。检查调用堆栈。如果您很幸运,它将陷入您自己的代码中发生异常的位置。如果异常不在陷阱中的代码模块中,请单击向上调用堆栈(在此处显示的列表中),直到到达代码中可以检查调用者参数的部分,它是通常很容易发现那时出错的地方。 0x44非常像ASCII&#39; $&#39;,你的txt中有$吗?