每次运行此程序时都会出现此错误:
分段错误
testing.cpp
#include <iostream>
#include <cstdint>
#include <SDL.h>
#include <SDL_image.h>
#include "Surface.h"
#include "Point2D.h"
int main() {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
std::cerr << "Can not init SDL" << std::endl;
return -1;
}
SDL_Surface *scr = SDL_SetVideoMode(800, 600, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
if ( scr == NULL ) {
std::cerr << "Can not open window" << std::endl;
return -1;
}
SDL_WM_SetCaption("Test Surface class", NULL);
Surface screen;
Surface image;
screen.set(SDL_GetVideoSurface());
if (image.load("./data/images/logo.png") == false) {
std::cerr << "Can not open file" << std::endl;
return -1;
}
bool run = true;
uint32_t sticks = SDL_GetTicks();
while(run) {
if (screen.draw(image, Rectangle(0, 0, image.getWidth(), image.getHeight()), Point2D(0, 0)) == false) {
std::cerr << "Can not draw to window" << std::endl;
return -1;
}
if ((SDL_GetTicks() - sticks)/1000 > 5) {
std::cerr << "End of time" << std::endl;
run = false;
}
SDL_Flip(screen.sdlSurface());
}
std::cerr << "Done" << std::endl;
SDL_Quit();
return 0;
}
有Surface类
的源代码#include "Surface.h"
#include "Color.h"
Surface::Surface() {
this->surface = NULL;
}
Surface::~Surface() {
SDL_FreeSurface(this->surface);
this->surface = NULL;
}
bool Surface::draw(Surface source, Rectangle source_area, Point2D position) {
SDL_Rect sr = source_area.sdlRect();
SDL_Rect tr = {position.getX(), position.getY(), 0, 0};
std::cout << sr.x << "," << sr.y << "," << sr.w << "," << sr.h << std::endl;
std::cout << tr.x << "," << tr.y << "," << tr.w << "," << tr.h << std::endl;
std::cout << source.sdlSurface() << std::endl;
std::cout << this->surface << std::endl;
// TR and SR are currently unused. Just for case of testing
if (SDL_BlitSurface(source.sdlSurface(), NULL, this->surface, NULL) != 0) {
return false;
}
return true;
}
bool Surface::fill(Color color, Rectangle area) {
SDL_Rect tr = area.sdlRect();
std::cout << tr.x << "," << tr.y << "," << tr.w << "," << tr.h << std::endl;
std::cout << (int)color.sdlColor() << std::endl;
if ( SDL_FillRect(this->surface, &tr, color.sdlColor()) != 0) {
return false;
}
return true;
}
Rectangle Surface::getSize() {
return Rectangle(0, 0, this->getWidth(), this->getHeight());
}
bool Surface::load(std::string file) {
SDL_Surface *src = IMG_Load(file.c_str());
if (src == NULL) {
std::cout << "cyh" << std::endl;
std::cout << IMG_GetError() << std::endl;
return false;
}
this->surface = SDL_DisplayFormatAlpha(src);
if (this->surface == NULL) {
std::cout << "cyh1" << std::endl;
std::cout << SDL_GetError() << std::endl;
return false;
}
SDL_FreeSurface(src);
src = NULL;
return true;
}
void Surface::set(SDL_Surface *surface) {
this->surface = surface;
}
void Surface::set(Surface surface) {
this->surface = surface.sdlSurface();
}
问题可能在于绘图功能。如果我改变这一行:
if (SDL_BlitSurface(source.sdlSurface(), NULL, this->surface, NULL) != 0) {
为:
if (SDL_BlitSurface(IMG_Load("./data/images/logo.png"), NULL, this->surface, NULL) != 0) {
一切似乎都没问题。你能给我一个建议吗?问题应该在哪里?
答案 0 :(得分:3)
您违反了The Rule of 3。
您需要定义复制构造函数和复制赋值运算符才能使其正常工作。
当您将Surface
传递给draw方法时,您正在制作它的副本。由于您正在管理Surface类中的资源(SDL_Surface*
),因此您将有多个类的实例指向同一个表面,因此当调用析构函数时,您将释放相同的{ {1}}不止一次。
编辑:我建议您通过const引用传递参数。您想要绘制它们时,无需复制SDL_Surface*
个对象。
此:
Surface
会变成这样:
bool Surface::draw(Surface source, Rectangle source_area, Point2D position);
这也适用于您的其他功能。