C++ 使用虚拟析构函数c+;删除指向基类的指针(*&;)+;

C++ 使用虚拟析构函数c+;删除指向基类的指针(*&;)+;,c++,pointers,memory-management,memory-leaks,polymorphism,C++,Pointers,Memory Management,Memory Leaks,Polymorphism,所以,我有一个运行在非常旧的系统(2006-2007)上的游戏服务器,它在玩家登录时创建玩家对象,在创建怪物时创建怪物对象,在npc出现时创建npc对象。所有这些类都源自生物类,并且都有虚拟析构函数。因此,当我创建这些对象时,我将它们添加到一个生物向量(不是一个实际的STL向量,而是一个定制的模板)中,操作符()重载。我编写了这个虚拟代码,以便于显示 vector<Creature *> CreatureList(100); template <typename T>

所以,我有一个运行在非常旧的系统(2006-2007)上的游戏服务器,它在玩家登录时创建玩家对象,在创建怪物时创建怪物对象,在npc出现时创建npc对象。所有这些类都源自生物类,并且都有虚拟析构函数。因此,当我创建这些对象时,我将它们添加到一个生物向量(不是一个实际的STL向量,而是一个定制的模板)中,操作符()重载。我编写了这个虚拟代码,以便于显示

vector<Creature *> CreatureList(100);

template <typename T>
struct vector {
    vector(int InitialSize);
    int InitialSize;
    T& operator()(int i);
    T* Entry; // At constructor, this is 'Entry = new T[InitialSize];' and is deleted at destructor.
};

struct Creature {
    Creature();
    virtual ~Creature();
    bool IsOnMap;
    char Name[30];
};

struct Player : Creature {
    Player();
    virtual ~Player();
    int PlayerState;
    int PlayerID;
};

struct Monster : Creature {
    Monster();
    virtual ~Monster();
    int SpawnPosX, SpawnPosY;
    int Health;
};

struct NPC : Creature {
    NPC();
    virtual ~NPC();
    Object TradeChest;
    int SpawnPosX, SpawnPosY;
};

int OnPlayerLogin() {
    Player *pl = new Player;
    CreatureList(NextCreatureID++) = pl;
    return PlayerID;
}

void OnMonsterSpawn() {
    Monster *mn = new Monster;
    CreatureList(NextCreatureID++) = mn;
}

void OnNPCSpawn() {
    NPC *npc = new NPC;
    CreatureList(NextCreatureID++) = npc;
}

void ProcessAllCreatures() {
    for (int i = 0; i < NextCreatureID; i++) {
        Creature* cr = CrList(i); // this doesn't return Creature* but actually Creature*&
        if (!cr)
            continue;

        if (!cr->IsOnMap)
            delete cr; // This spits a SIGSEGV (Segmentation fault).
    }
}
向量创建列表(100);
模板
结构向量{
向量(int InitialSize);
int初始大小;
T&运算符()(int i);
T*Entry;//在构造函数中,这是“Entry=newt[InitialSize];”,并在析构函数中删除。
};
结构生物{
生物();
虚拟生物();
bool-IsOnMap;
字符名[30];
};
结构玩家:生物{
Player();
虚拟~Player();
int PlayerState;
int PlayerID;
};
结构怪物:生物{
怪物();
虚拟~Monster();
int SpawnPosX,SpawnPosY;
国际卫生组织;
};
结构NPC:生物{
NPC();
虚拟~NPC();
实物交易箱;
int SpawnPosX,SpawnPosY;
};
int OnPlayerLogin(){
Player*pl=新玩家;
CreatureList(NextCreatureID++)=pl;
返回PlayerID;
}
void OnMonsterSpawn(){
怪物*mn=新怪物;
CreatureList(NextCreatureID++)=mn;
}
void OnNPCSpawn(){
NPC*NPC=新的NPC;
CreatureList(NextCreatureID++)=npc;
}
void processallbiotes(){
对于(int i=0;iIsOnMap)
delete cr;//这将抛出一个SIGSEGV(分段错误)。
}
}
此伪代码假定所有初始化都在构造函数中完成
NextCreatureID
只是一个用作索引的自动增量变量。自定义向量类只是一个自动调整大小的数组,运算符()将始终返回对实际对象的引用(由于内部代码约定,这不能更改)

问题是它向进程发送一个SIGSEGV,如果我尝试
delete&cr
,由于指针无效,我会得到SIGABRT。那么,有没有办法在不改变向量类的情况下解决这个问题?(这对我来说是不可能的,因为我说的合作工作)


不会像你想的那样工作
delete
ing指针不会将其重置为
nullptr
。在您第一次调用processAllBiotes()时,一切都可以正常工作,当您第二次调用它时,您将删除已删除的指针,因为在查看已删除的指针时,您将永远不会继续执行

我犯了这样一个愚蠢的错误。我得重读那本旧指针书。我已将此标记为答案。
if (!cr)
    continue;