c++ - 理解为什么会出现段错误

标签 c++ segmentation-fault

我有一些代码,我试图找出为什么我在这里遇到段错误:

我将 SpeedEffect 添加到 EffectStack 中,效果很好。但是,如果我尝试删除其中一个 Effects(已在堆栈中),我必须调用 effect.removeEffect()。这会导致段错误。

如果我尝试从 TestStack() 函数调用 effect.removeEffect(),它运行良好(并在控制台上打印出预期的“移除速度效果” )

void Test::testStack() {
    Story* st = new Story; //<-- only needed for initialization of an Effect
    Veins::TraCIMobility* mob = new Veins::TraCIMobility; //<-- only needed for initialization of an Effect
    SpeedEffect a = SpeedEffect(1.0, st, mob);

    a.removeEffect();  //<-- This one works quite well
    (&a)->removeEffect();  //<-- Clearly, this works too

    EffectStack s;
    s.addEffect(&a);  //<-- Adds a Effect to the effect Stack
    assert(s.getEffects().size() == 1);

    s.removeEffect(&a); //<-- Try to remove effect from stack
}

StackEffect 实现如下:

class Effect {
public:
    Effect(Story* story, Veins::TraCIMobility* car) :
        m_story(story), m_car(car) {}

    virtual void removeEffect() = 0;
private:
    Story* m_story;
protected:
    Veins::TraCIMobility* m_car;
};


class SpeedEffect : public Effect {
public:
    SpeedEffect(double speed, Story* story, Veins::TraCIMobility* car):
        Effect(story, car), m_speed(speed){}

    void removeEffect() {
        std::cout << "speed effect removed" << std::endl;
    }

private:
    double m_speed;
};


class EffectStack {
public:
    void addEffect(Effect* effect) {
        if(std::count(m_effects.begin(), m_effects.end(), effect) == 0) {
            m_effects.push_back(effect);
        }
    }

    void removeEffect(Effect* effect) {
        if(effect == m_effects.back()) {
            //effect is pointing on the same address like its doing before, but causes the seg fault
            m_effects.back()->removeEffect(); //<--- Seg Fault here!!
            effect->removeEffect(); //<-- if I use this, seg fault too
            m_effects.pop_back();
        }else {
            removeFromMiddle(effect);
        }
    }

    const std::vector<Effect*>& getEffects() {
        return m_effects;
    }

private:
    std::vector<Effect*> m_effects;
};

我希望这段代码足够了,我已经删除了所有未被测试场景调用的函数。

有没有问题,因为speedEffect a的地址在Stack中变得无效了?

也许你可以帮我解决这个问题。


对问题的新思考: 不,我测试了更多,这让我更加困惑:

void dofoo(SpeedEffect* ef) {
    ef->removeEffect(); //<-- breaks with a segmentation fault
}

void Test::testStack() {
    Story* st = new Story;
    Veins::TraCIMobility* mob = new Veins::TraCIMobility;
    SpeedEffect e = SpeedEffect(3.0, st, mob);

    e.removeEffect(); //<-- Works fine
    (&e)->removeEffect(); //<-- Works fine also
    dofoo(&a); //<-- Jumps into the dofoo() function
}

最佳答案

这可能对您没有帮助,但是持久化基于堆栈的对象的地址通常不是一个好主意。在您上面的代码中,它可能没问题,因为您知道 EffectStack 不会比您的效果长寿。

如果你这样做,崩溃是否仍然发生:

SpeedEffect* a = new SpeedEffect(1.0, st, mob);

(并相应地调整其余代码?)这当然会泄漏内存,但它会告诉您问题是否出在 SpeedEffect 被破坏上。另一种选择是为 SpeedEffect 提供一个析构函数(并为 Effect 提供一个虚拟析构函数)并在内部设置一个断点以查看编译器何时销毁“a”。

关于c++ - 理解为什么会出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33372631/

相关文章:

c++ - 派生类中重载最终函数

c++ - 插入 vector

c - 函数之间的文件指针上的 SegmentFault

c++ - 转换为模板

c++ - 模拟 Fn+F11 按键

c++ - 在单眼视觉里程计中使用 3d-2d 运动估计的相机位置

c++ - 扩展 Visual Studio C++ 构建过程

时间:2019-03-17 标签:c++segfault: char pointers

c - 包含两个双指针的结构体,访问第二个双指针时出现段错误

char* 内存分配错误,除非使用 'top -b -n 1'