我有一些代码,我试着弄清楚,为什么我在这里遇到分段错误:
我向SpeedEffect
添加EffectStack
,效果非常好。但是如果我尝试删除其中一个Effects
(已经在堆栈中),我必须调用effect.removeEffect()
。这会导致分段错误。
如果我尝试从effect.removeEffect()
函数调用TestStack()
,它运行良好(并在控制台上打印预期的“速度效果已删除”)
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
}
Stack
和Effect
的实施方式如下:
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
}
答案 0 :(得分:0)
这可能对你没有帮助,但坚持基于堆栈的对象的地址通常不是一个好主意。在你上面的代码中它可能没问题,因为你知道EffectStack不会比你的效果更长。
如果你这样做,崩溃仍然会发生:
SpeedEffect* a = new SpeedEffect(1.0, st, mob);
(并相应地调整其余的代码?)这当然会泄漏内存,但它会告诉你问题是SpeedEffect被破坏了。另一个选择是给SpeedEffect一个析构函数(和一个虚拟析构函数)并在里面设置一个断点,看看编译器什么时候正在销毁&#39; a&#39;。
答案 1 :(得分:0)
Story* st = new Story; //<-- only needed for initialization of an Effect
Veins::TraCIMobility* mob = new Veins::TraCIMobility; //<-- only needed for initialization
我没有看到delete st
和delete mob
- 在void Test::testStack()
中为这些对象分配了内存但未明确释放。
在函数末尾添加这两个语句,然后重试。
答案 2 :(得分:0)
我发现了这个问题。 我正在使用omnet Simulation框架,如果我实现了TraciMobility,就会发生意想不到的事情。 没有它,没有错误..