Я работаю над простой игрой с использованием C++ и Allegro. Я столкнулся с ошибкой времени выполнения Access violation
относительно vector
structs
, которые содержат unique_ptrs
до ALLEGRO_BITMAPs
.Копирование вектора structs unique_ptrs
Вот моя декларация структуры.
struct Skin {
std::unique_ptr<ALLEGRO_BITMAP> img;
Skin();
Skin(ALLEGRO_BITMAP*);
Skin& operator=(const Skin& s);
Skin(const Skin& s);
};
И вот определения конструкторов в другом файле.
Skin::Skin() {
img.reset();
}
Skin::Skin(ALLEGRO_BITMAP* bitmap) {
img.reset(bitmap);
}
Skin::Skin(const Skin& s) {
img.reset(s.img.get());
}
Skin& Skin::operator=(const Skin& s) {
img.reset(s.img.get());
return *this;
}
Вот код, который вызывается перед нарушением прав доступа.
generateBase(world, display.get());
Какой вызов вызывает эта функция.
void generateBase(World& world, ALLEGRO_DISPLAY* display) {
int x = TILESIZE - WIDTH;
int y = HEIGHT - TILESIZE;
int groundWidth = 3 * WIDTH - 2 * TILESIZE;
Point min{ x, y };
Point max{ x + groundWidth, y + (int)TILESIZE };
ALLEGRO_BITMAP* black = al_create_bitmap(groundWidth, TILESIZE);
ALLEGRO_BITMAP* white = al_create_bitmap(groundWidth, TILESIZE);
al_set_target_bitmap(black);
al_clear_to_color(al_map_rgb(0, 0, 0));
al_set_target_bitmap(white);
al_clear_to_color(al_map_rgb(255, 255, 255));
al_set_target_bitmap(al_get_backbuffer(display));
std::cout << "Errors incoming!" << endl;
createPlayer(world, x, y, 0, 0, 5, vector <AABB> { AABB(min, max) }, vector <Skin> { Skin(black), Skin(white) });
std::cout << "Did we make it?" << endl;
}
Эта функция, в свою очередь, вызывает эту функцию.
unsigned int createPlayer(World& world, int x, int y, float dx, float dy, float speed, vector<AABB>& mesh, vector<Skin>& imgs) {
unsigned int entity = newEntityIndex(world);
world.masks[entity].set(COMPONENT_TYPE);
world.masks[entity].set(COMPONENT_POINT);
world.masks[entity].set(COMPONENT_UNITVECTOR);
world.masks[entity].set(COMPONENT_SPEED);
world.masks[entity].set(COMPONENT_COLLISIONMESH);
world.masks[entity].set(COMPONENT_SKINLIST);
world.types[entity] = TYPE_PLAYER;
world.points[entity] = Point(x, y);
world.unitVectors[entity] = UnitVector(dx, dy);
world.speeds[entity] = Speed(speed);
world.collisionMeshes[entity].mesh = mesh;
cout << "Starting vector copy" << endl;
for (auto skin : imgs) {
world.skinLists[entity].imgs.push_back(move(skin));
}
cout << "Ending vector copy" << endl;
return entity;
}
Это мой дед для unique_ptr.
namespace std {
template<>
class default_delete <ALLEGRO_BITMAP> {
public:
void operator()(ALLEGRO_BITMAP* ptr) {
cout << ptr << endl;
al_destroy_bitmap(ptr);
}
};
}
Вот выход.
Errors incoming!
Starting vector copy
00AF9468
00AF9468
Когда я изменил мой createPlayer
вызов в generateBase
путем удаления Skin(white)
, выход изменен.
Errors incoming!
Starting vector copy
00799468
Ending vector copy
00799468
Изменение выхода у меня немного озадачило, но мой самый большой вопрос в том, что мне нужно сделать, чтобы изменить о том, как скопировать мой vector
из structs
из unique_ptrs
так, что я не пытаюсь удалить тот же указатель дважды.
Заранее благодарен!
1) Вы уже говорили о [минимальные полные примеры] (http://stackoverflow.com/help/mcve), 2) ваш 'Skin :: operator =' нарушает правила 'std :: unique_ptr'. – Beta