Tôi gặp vấn đề với một segfault mà tôi không thể tìm ra. Đó là từ số EntityManager
cho một công cụ trò chơi nhỏ mà tôi đang thực hiện. Tôi có thể thêm Ship Entity
và Tàu có thể thêm 1 Bullet Entity
, nhưng nó sẽ phân cách nếu tôi cố gắng thêm nhiều hơn 1 Bullet
. Tôi đã cố gắng để figgure này ra cho ngày hôm qua bây giờ. Dưới đây là một trích đoạn nhỏ từ mã thực tế.vectơ xóa unique_ptr?
#include <vector>
#include <memory>
struct EntityManager;
struct Entity {
Entity(EntityManager* manager) : manager(manager) { }
virtual ~Entity() { }
virtual void update() = 0;
EntityManager* manager;
};
struct EntityManager {
void update() {
for (auto& entity : entities) {
entity->update();
}
}
void add(Entity* e) {
entities.emplace_back(e);
}
std::vector<std::unique_ptr<Entity>> entities;
};
struct Bullet : public Entity {
Bullet(EntityManager* manager) : Entity(manager) { printf("Bullet ctor\n"); }
virtual void update() override { }
};
struct Ship : public Entity {
Ship(EntityManager* manager) : Entity(manager) { }
virtual void update() override {
printf("Adding Bullet\n");
manager->add(new Bullet(manager));
}
};
int main() {
EntityManager manager;
manager.add(new Ship(&manager));
int loops{0};
while (loops < 100) {
manager.update();
loops++;
printf("Completed Loop #%d\n", loops);
}
return 0;
}
Trong mã thực tế, mọi thứ đều nằm trong tệp .h/.cpp của riêng chúng và các lớp thay vì cấu trúc, nhưng vấn đề thì giống nhau. Kết quả là `Thêm Bullet // Bullet ctor // Hoàn Vòng # 1 // Thêm Bullet // Bullet ctor // Signal: SIGSEGV (lỗi Segmentation)
Các segfault xảy ra trong EntityManager::update()
trên dòng entity->update();
.
'EntityManager' cần các thao tác di chuyển tùy chỉnh để cập nhật con trỏ' manager' của thực thể. – dyp
Khi bạn cập nhật các thực thể, vòng lặp đó sẽ thêm nhiều thực thể làm mất hiệu lực trình vòng lặp của bạn. Bạn không thể thêm vào vectơ của bạn trong khi bạn đang ở giữa vòng lặp thông qua nó. – Galik
[Viết trò chơi không phải là công cụ] (http://geometrian.com/programming/tutorials/write-games-not-engines/) là một điều tốt để đọc. Điều đó nói rằng, thay vì thêm mọi thứ ngay lập tức hoặc phá hủy mọi thứ ngay lập tức, bạn có thể trì hoãn các hoạt động đó sau vòng lặp cập nhật, thông qua các sự kiện hoặc bất kỳ điều gì bạn thấy thích hợp, để bạn không làm mất hiệu lực trình vòng lặp. – aslg