我的程序中出现了一个奇怪的分段错误。 Dlist是一个类,它创建一个链接列表,其中包含从动态列表中插入和删除项目的操作。我很肯定我这个类的实现是正确的,但是这段代码产生了一个seg错误。奇怪的是,当我使我的atleastTwo和atleastOne函数通过引用传递时,seg错误消失并且所有内容都会编译。任何人都可以解释这个问题吗?
bool atleastTwo(Dlist<double> stack){
try{
stack.removeFront();
stack.removeFront();
} catch(emptyList e){
cout << "Not enough operands\n";
return false;
}
return true;
}
bool atleastOne(Dlist<double> stack){
try{
stack.removeFront();
} catch(emptyList e){
cout << "Not enough operands\n";
return false;
}
return true;
}
void processInput(inputs usrInput, Dlist<double> &stack){
switch(usrInput){
case i_add:
if(atleastTwo(stack)){doOperation(stack, add);}
break;
case i_subtract:
if(atleastTwo(stack)){doOperation(stack, subtract);}
break;
case i_multiply:
if(atleastTwo(stack)){doOperation(stack, multiply);}
break;
case i_divide:
if(atleastTwo(stack)){doOperation(stack, divide);}
break;
case i_negation:
if(atleastOne(stack))negation(stack);
break;
case i_duplicate:
if(atleastOne(stack)){duplicate(stack);}
break;
case i_reverse:
if(atleastTwo(stack)){reverse(stack);}
break;
case i_print:
if(atleastOne(stack)){print(stack);}
break;
case i_clear:
clear(stack);
break;
case i_printAll:
printAll(stack);
break;
default:
break;
}
}
T *removeFront();
// MODIFIES this
// EFFECTS removes and returns first object from non-empty list
// throws an instance of emptyList if empty
由于
答案 0 :(得分:1)
关于问题本身,我不知道你的代码会如何发生段错误。我怀疑问题出在Dlist的代码中,可能是一个糟糕的析构函数?
要解决您的问题,您可以在Dlist中实现元素计数并检查它。但也许你不允许修改Dlist。避免跳转代码和太多测试的首选解决方案将遵循建议。而不是测试操作数的数量,只需尝试它,并将异常处理程序放在您的处理方法中。第二个解决方案的问题是堆栈可能保持不一致状态:这意味着您无法继续计算并应从头开始重新启动。
void processInput(inputs usrInput, Dlist<double> &stack)
{
try{
// .... your old code WITHOUT ifs
} catch(emptyList e){
cout << "Not enough operands\n";
}
}
我认为后者是一种方法,您可以保留堆栈的副本并在一个副本上进行计算。这种方式的性能会更好,代码更易于阅读和理解。
我希望它有所帮助。
答案 1 :(得分:0)
如果您通过值(不使用引用),则每次都有效地复制。究竟如何令人困惑的东西还不清楚,你需要准确研究各种拷贝构造器正在做什么。但肯定通过引用传递你的意思是什么?你为什么要复制整个系列?
答案 2 :(得分:0)
在盯着你的Dlist实现代码很长一段时间(乍一看看起来不错),我认为问题在于:
template <typename T>
Dlist<T>::Dlist(const Dlist &l){
removeAll();
copyAll(l);
}
在将removeAll()
(和first
)初始化为NULL之前调用last
将导致错误的事情,因为在那里执行了操作。
Dlist设计的另一个问题是你持有原始指针(这很棘手但不一定是坏的,假设每个人都清楚用户负责删除它们),但你已经实现了深层复制机制。除非您手动删除其内容,否则临时Dlist对象将泄漏,您传递给atLeastOne
和atLeastTwo
函数的副本也将泄漏。