【问题标题】:Seg Fault at return statement in function函数中返回语句的段错误
【发布时间】:2012-10-20 02:06:39
【问题描述】:

我的程序应该将提示从中缀转换为后缀。到目前为止,通过调试器和其他各种方法,我已经找到了我的段错误的确切点,但不明白为什么。

这是我的代码:

这里是 itop.h:

using namespace std;
#include <cstdlib>
#include <iostream>

class sNode{
    public:
       char data;
       sNode *next;
};

class stack{
    public:
        sNode *head;
        void push (char);
        sNode pop();
        int rank(char);
        stack()
        {
        cout << "Initiliazing stack." << endl;
        }
};

这是我的 itop.cpp 文件:

    #include "itop.h"

    void stack::push (char a)
    {
            // cout << "Pushing " << a << endl;
            sNode *sn;
            sn = new sNode;
            sn->data = a;
            sn->next = head;
            head = sn;
    }

    sNode stack::pop()
    {
            // cout << "Popping stack." << endl;
            sNode *sn;
            sn = head;
            head = head->next;
            return *sn;
    }

    int stack::rank(char x)
    {
            int num = 0;
            // cout << "Checking rank." << endl;
            if(x == '\0')
            {
                    num = 1;
                    // cout << "Checking for null" << endl;
                    return num;
            }
            else if(x == '+' || x == '-')
            {
                    num = 2;
                    // cout << "Checking if + or -" << endl;
                    return num;
                    // cout << "After return." << endl;
            }
            else if(x == '*' || x == '/')
            {
                    num = 3;
                    // cout << "Checking for * or /" << endl;
                    return num;
            }
            else
                    cout << "Error! Input not valid!" << endl;
    }

这是 main.cpp:

using namespace std;
#include <iostream>
#include <cstdlib>
#include <cstring>
#include "itop.h"

int main()
{
char *temp1;            //Instantiating variables.
char *temp2;
temp1 = new char[20];
temp2 = new char [20];
stack s;
do              //Checking commands.
{
    cout << "infix_to_postfix> ";
    cin >> temp1;
    if(strcmp(temp1, "quit") == 0)
    {
        return 0;
    }
    if(strcmp(temp1, "convert") != 0)
    {
        cout << "Error! Invalid command." << endl;
    }
    cin >> temp2;
    if(strcmp(temp1, "convert") == 0)
    {
        for(int i=0; i<sizeof(temp2); i++)
        {
            if(isdigit(temp2[i]))
            {
                cout << atoi(&temp2[i]);
            }
            else if(s.rank(temp2[i]) < s.rank(s.head->data))
            {
                sNode temp = s.pop();
                cout << temp.data;
            }
            else
            {
                s.push(temp2[i]);
            }
        }
    }
    else
    {
        cout << "Error! Command not supported." << endl;
    }
}while(strcmp(temp1, "quit") != 0);

return 0;
}

函数调用于

else if(s.rank(temp2[i]) < s.rank(s.head->data))

问题出在这里:

            else if(x == '+' || x == '-')
            {
                    num = 2;
                    // cout << "Checking if + or -" << endl;
                    return num;
                    // cout << "After return." << endl;
            }

特别是在返回 num 之前,我收到“分段错误(核心转储)”错误消息。我使用过 gdb,我所知道的是,在“检查 + 或 -”之后,我看到“$1 = 2”。我不太确定这意味着什么,但这是我想要返回的。

感谢您的帮助。

【问题讨论】:

  • 为什么要创建变量num?可以直接返回整数。
  • 我只是想简化代码。 :) @OP:请向我们展示调用函数。
  • 调用函数是必须的。返回时的段错误通常是您在说返回之前在某处损坏堆栈的症状 - 但目前尚不清楚您在这里可能会做什么会导致这种情况。
  • 我认为返回一个直接的 int 可能是问题所在。我只是没有看到将它改回来的意义。
  • 当函数的返回类型是 int 时,返回 int 永远不会成为问题。当然,如果您以不同的方式使用函数的返回值或使用另一种数据类型,在您的调用函数中,也可能出现段错误。能否贴出调用函数代码?

标签: c++ segmentation-fault fault infix-notation postfix-notation


【解决方案1】:

您的代码中有很多错误。您的堆栈实现是错误的。 push() 例如只设置head 一遍又一遍。这导致您的堆栈类只能容纳一个元素。 next 从未设置为任何内容,因此它包含随机垃圾。再往下,你有这个:

for(int i=0; i<sizeof(temp2); i++)

sizeof(temp2) 不会给您temp2 指向的字符串的字符数。它为您提供指针 temp2 本身的大小。此外,您最终会从一个空堆栈中读取s.head,这将是一个指向随机垃圾的指针。到那时,所有的赌注当然都结束了。除了崩溃和燃烧,你别无所求。

【讨论】:

  • @askmish 不。普通的老眼睛。这意味着,我可能是错的 :-)
  • 不使用sn-&gt;next = head; head=sn 将下一个设置为上一个头部; Head 只是堆栈的顶部,所以当我在顶部添加一些东西时,新节点必须成为头部,next 指向旧头部。不过,谢谢你的 sizeof。
【解决方案2】:

修正1:写一个合适的构造函数。

    stack()
    {
    head=NULL;
    cout << "Initiliazing stack." << endl;
    } 

修复2:写一个额外的方法来检查堆栈是否为空。

int stack::empty()
{
    if(head == NULL)
      return true;
    else
      return false;
}

修复3:在使用堆栈数据之前检查堆栈是否为空。

else if(!s.empty() && s.rank(temp2[i]) < s.rank(s.head->data))
{
 ...
}

修复 4:修复其余代码逻辑。

【讨论】:

  • @OP:你也可以使用 STL 堆栈。
  • 我们不允许使用 Stack 库。非常感谢,问!检查空堆栈确实很有帮助。现在我只需要弄清楚中缀到后缀的正确顺序(基本上是本练习的重点),然后我就完成了。
猜你喜欢
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
  • 2015-04-13
  • 2013-10-06
  • 1970-01-01
相关资源
最近更新 更多