C++ 为什么获取munmap\u chunk():无效指针:错误

C++ 为什么获取munmap\u chunk():无效指针:错误,c++,C++,所以我在做一些赋值,当我试图在类字符中的“setwearm”函数中“删除”先前分配的武器行为时,突然遇到了这个“无效指针”错误。有没有人能指出问题所在 #include <iostream> using namespace std; class WeaponBehaviour{ public: virtual void useWeapon() = 0; }; class SwordBehaviour : public WeaponBehaviour { public:

所以我在做一些赋值,当我试图在类字符中的“setwearm”函数中“删除”先前分配的武器行为时,突然遇到了这个“无效指针”错误。有没有人能指出问题所在


#include <iostream>
using namespace std;

class WeaponBehaviour{
public:
    virtual void useWeapon() = 0;
};

class SwordBehaviour : public WeaponBehaviour {
public:
    void useWeapon()
    {
        cout << "slash slash"<< endl;
    }
};
class BowAndArrowBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        cout << "suss suss"<< endl;
    }
};

class KnifeBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        cout << "chak chakk"<< endl;
    }
};
class AxeBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        cout << "chop chop"<< endl;
    }
};



class Character{
protected:
    WeaponBehaviour* weaponBehaviour;
public:
    Character(){

    }
    ~Character(){
        if(weaponBehaviour != NULL)
        {
            delete weaponBehaviour;
        }
    }
    void setWeapon(WeaponBehaviour* newWeapon)
    {
        if(weaponBehaviour!= NULL )
            delete weaponBehaviour;

        weaponBehaviour = newWeapon;
    }
    void fight()
    {
        weaponBehaviour->useWeapon();
    }
};

class King : public Character
{
public:
    King(){
        setWeapon(new SwordBehaviour);
    }
};

class Queen : public Character
{
public:
    Queen(){
        setWeapon(new KnifeBehavior);
    }
};

int main() {
    King king ;
    king.fight();
    Queen queen ;
    queen.fight();
    queen.setWeapon(new AxeBehavior);
    queen.fight();
    return 0;
}

#包括
使用名称空间std;
阶级武器行为{
公众:
虚拟武器()=0;
};
职业剑士行为:公共武器行为{
公众:
无效武器()
{

cout您需要将
weaponbehavior
初始化为
nullptr
否则
weaponbehavior
将有一个未定义(可能非空)的值,并且

if(weaponBehaviour!= NULL)
  delete weaponBehaviour;
将传递if语句并删除无效指针

编译器还应警告您(如果已启用警告),您有一个没有虚拟析构函数的虚拟类。这会导致通过
weaponBehavior
指针删除对象时出现未定义的行为。
weaponBehavior
的正确声明为:

class WeaponBehaviour{
public:
    virtual WeaponBehaviour() {}
    virtual void useWeapon() = 0;
};
这并没有在代码中造成问题,但您应该知道

使用
std::unique\u ptr
可以解决上述所有问题,并使您的代码更简单、更安全:

#include <iostream>
#include <memory>

class WeaponBehaviour{
public:
    virtual ~WeaponBehaviour(){}
    virtual void useWeapon() = 0;
};

class SwordBehaviour : public WeaponBehaviour {
public:
    void useWeapon()
    {
        std::cout << "slash slash\n";
    }
};
class BowAndArrowBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        std::cout << "suss suss\n";
    }
};

class KnifeBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        std::cout << "chak chakk\n";
    }
};
class AxeBehavior : public WeaponBehaviour {
public:
    void useWeapon()
    {
        std::cout << "chop chop\n";
    }
};



class Character{
protected:
    std::unique_ptr<WeaponBehaviour> weaponBehaviour;
public:
    void setWeapon(std::unique_ptr<WeaponBehaviour>&& newWeapon)
    {
        weaponBehaviour = std::move(newWeapon);
    }
    void fight()
    {
        weaponBehaviour->useWeapon();
    }
};

class King : public Character
{
public:
    King(){
        setWeapon(std::make_unique<SwordBehaviour>());
    }
};

class Queen : public Character
{
public:
    Queen(){
        setWeapon(std::make_unique<KnifeBehavior>());
    }
};

int main() {
    King king ;
    king.fight();
    Queen queen ;
    queen.fight();
    queen.setWeapon(std::make_unique<AxeBehavior>());
    queen.fight();
    return 0;
}
#包括
#包括
阶级武器行为{
公众:
虚拟~weaponbehavior(){}
虚拟武器()=0;
};
职业剑士行为:公共武器行为{
公众:
无效武器()
{

std::你是否应该尝试使用调试器。对于此类问题,调试器是一个非常有用的工具。还可以使用警告进行编译。你在
weaponbehavior
中没有虚拟析构函数,因此你代码中的删除是UB。如果我正确读取回溯(其格式有点混乱),那么这与你的代码相去甚远。你的代码(你应该把它带到codereview.stackexchange.com,顺便说一句,还有很多地方需要改进)对我来说,这似乎不是原因。唯一明显的错误是缺少虚拟析构函数。@PaulRooney感谢你的提示,问题是因为没有使用虚拟析构函数。添加它解决了问题。好吧,很酷。我添加了它,但仍然有一个segfault。你应该将
-Wall-Wextra-pedantic
标志传递给GCC,还应该传递
-g
以包含调试符号。使用此GCC会警告dtor。如果您从未将
武器行为
初始化为
NULL
,则它有一个可能不为NULL的不确定值,因此您将尝试
删除一些您从未
新建的
'd