C++ C++;奇异分段断层

C++ C++;奇异分段断层,c++,linked-list,segmentation-fault,C++,Linked List,Segmentation Fault,我的程序中出现了一个奇怪的分段错误。Dlist是一个创建链表的类,该链表包含从动态列表中插入和删除项目的操作。我确信这个类的实现是正确的,但是这个代码产生了seg错误。奇怪的是,当我通过引用传递我的atlesttwo和atlestone函数时,seg错误消失了,所有的东西都编译了。有人能解释一下这个问题吗 bool atleastTwo(Dlist<double> stack){ try{ stack.removeFront(); stack.removeFront(

我的程序中出现了一个奇怪的分段错误。Dlist是一个创建链表的类,该链表包含从动态列表中插入和删除项目的操作。我确信这个类的实现是正确的,但是这个代码产生了seg错误。奇怪的是,当我通过引用传递我的atlesttwo和atlestone函数时,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
bool至少两个(数据列表堆栈){
试一试{
stack.removeFront();
stack.removeFront();
}捕获(空列表e){

cout如果通过值传递(不使用引用)那么你每次都在有效地复制一个副本。这到底是如何让事情变得混乱的还不清楚,你需要确切地研究各种副本构造函数在做什么。但你的意思肯定是通过引用传递?你为什么要复制整个集合?

关于这个问题本身,我不知道从你的代码。我怀疑Dlist的代码中存在问题,可能是一个实现糟糕的析构函数

要解决您的问题,您可以在Dlist中实现元素计数并进行检查。但可能不允许您修改Dlist。为避免代码跳变和测试过多,首选的解决方案是遵循建议。与其测试操作数的数量,不如尝试一下,并将异常处理程序放在处理列表中第二种解决方案的问题是堆栈可能保持不一致的状态:这意味着您无法继续计算,应该从头开始重新启动

void processInput(inputs usrInput, Dlist<double> &stack)
{
  try{
    // .... your old code WITHOUT ifs
  } catch(emptyList e){
    cout << "Not enough operands\n";
  }
}
void processInput(输入usrInput、Dlist和stack)
{
试一试{
//…您的旧代码没有ifs
}捕获(空列表e){

cout在盯着Dlist实现代码看了很长一段时间后(乍一看似乎没有错),我认为问题出在这里:

template <typename T>
Dlist<T>::Dlist(const Dlist &l){
    removeAll();
    copyAll(l);
}
模板
数据列表::数据列表(常量数据列表和列表){
removeAll();
copyAll(l);
}
鉴于在那里执行的操作,在初始化
first
(和
last
)之前调用
removeAll()
)将导致不好的结果


Dlist设计的另一个问题是,您持有原始指针(这很棘手,但不一定是坏的,假设每个人都清楚用户负责删除它们),但您已经实现了深度复制机制。临时数据列表对象会泄漏,您传递给
atlestone
atlestone
函数的副本也会泄漏,除非您手动删除它们的内容。

您是否遵循三/五/任何规则?是的,是否存在副本构造函数?根据您的描述,问题是我们需要看一下Dlist的实现来确定问题所在(我怀疑这与指针复制有关)。是的,我遵循了3的规则。事实上,当我运行时,编译没有问题。(与Dlist的实现相同)。不同之处在于,这只是我的AtlestTwo函数的一个隔离。文件中没有其他函数。你不能只使用一个报告其大小的堆栈实现吗?复制,然后尝试/捕获以确定大小是荒谬的。我遇到的问题是,AtlestTwo/One的此实现无论如何都不需要更改列表(但同时检查其中是否有两个元素)。我似乎无法找到通过引用来解决此问题的方法。谢谢。这是一个更好的方法。