【问题标题】:Segfault in recursive function递归函数中的段错误
【发布时间】:2012-03-13 00:59:24
【问题描述】:

我在运行这段代码时遇到了段错误,我不知道为什么。注释掉特定行(标记如下)会删除段错误,这让我相信迭代器“i”的递归使用可能会造成问题,但即使将其更改为指针后,我也会得到段错误。

void executeCommands(string inputstream, linklist<linklist<transform> > trsMetastack)
{
int * i=new int;
(*i) = 0;
while((*i)<inputstream.length())
{
    string command = getCommand((*i),inputstream);
    string cmd = getArguments(command,0);
    //cout << getArguments(command,0) << " " << endl;


    if (cmd=="translate")
    {

        transform trs;
        trs.type=1;
        trs.arguments[0]=getValue(getArguments(command,2));
        trs.arguments[1]=getValue(getArguments(command,3));
        ((trsMetastack.top)->value).push(trs);
        executeCommands(getArguments(command,1),trsMetastack);
    }

    if (cmd=="group")
    { 
        //make a NEW TRANSFORMS STACK, set CURRENT stack to that one
        linklist<transform> transformStack;
        trsMetastack.push(transformStack);


        //cout << "|" << getAllArguments(command) << "|" << endl;
        executeCommands(getAllArguments(command),trsMetastack); // COMMENTING THIS LINE OUT removes the segfault

    }

    if (cmd=="line")
    { //POP transforms off of the whole stack/metastack conglomeration and apply them.


        while ((trsMetastack.isEmpty())==0)
        {
            while ((((trsMetastack.top)->value).isEmpty())==0)   //this pops a single _stack_ in the metastack
            { transform tBA = ((trsMetastack.top)->value).pop();
                cout << tBA.type << tBA.arguments[0] << tBA.arguments[1];
            }
            trsMetastack.pop();
        }


    }

“Metastack”是我必须在递归期间发送给函数的链表的链表,声明如下:

    linklist<transform> transformStack;
    linklist<linklist<transform> > trsMetastack;
    trsMetastack.push(transformStack);


    executeCommands(stdinstring,trsMetastack);

“Getallarguments”函数只是为了提取给定字符串的大部分,如下所示:

    string getAllArguments(string expr) // Gets the whole string of arguments
    {
        expr = expr.replace(0,1," "); 
        int space = expr.find_first_of(" ",1);
        return expr.substr(space+1,expr.length()-space-1);
    }

这里是链表类的定义。

    template <class dataclass> 
    struct linkm {
        dataclass value;     //transform object, point object, string... you name it
        linkm *next;
    };

    template <class dataclass> 
    class linklist 
    {
    public:
        linklist()
        {top = NULL;}
        ~linklist() 
        {}
        void push(dataclass num)
        {
            cout << "pushed";
            linkm<dataclass> *temp = new linkm<dataclass>;
            temp->value = num;
            temp->next = top;
            top = temp;
        }   
        dataclass pop()
        {

            cout << "pop"<< endl;
            //if (top == NULL) {return dataclass obj;}
            linkm<dataclass> * temp;
            temp = top;
            dataclass value;
            value = temp->value;
            top = temp->next;
            delete temp;
            return value;
        }
        bool isEmpty()
        {
            if (top == NULL) 
            return 1;
            return 0;
        }
        //  private:
        linkm<dataclass> *top; 
    };

感谢您抽出宝贵时间阅读本文。我知道这个问题很模糊,但我只是花了最后一个小时试图用 gdb 调试它,老实说我不知道​​它可能是什么。

【问题讨论】:

  • 如果你不知道为什么会出现段错误 - 在 gdb 下运行程序,或者使用生成的 coredump...
  • 我试过了。 gdb 说 top* 是空的,但除此之外它还给了我内存地址,而我对它一点经验都没有。 ://
  • Don’d use pointers for i here。请先解决这个问题。
  • getAllArguments 假设了很多关于字符串参数的事情。你假设它至少有一个字符。您还假设字符串包含一个空格,并且您将 string::find_first_of 的结果存储在一个 int 中,这不是一个 size_t。我们没有 getCommand 和 getArguments 函数,也没有您的测试输入,因此很难通过这种方式发现问题。
  • transform,和std::transform一样吗?

标签: c++ recursion segmentation-fault


【解决方案1】:

它可以是任何东西,但讽刺的是,我疯狂的猜测是:堆栈溢出。 您可能想尝试将数据结构作为引用传递,例如:

void executeCommands(string &inputstream, linklist<linklist<transform> > &trsMetastack)

但正如 Vlad 所指出的,您可能想熟悉 gdb。

【讨论】:

  • 哦,我仍然不擅长通过引用传递东西。在将它们更改为 & 引用后,我遇到了一些错误。尝试修复它们,没有骰子。某些东西在获得左值时需要右值,我尝试改变函数的工作方式......它变得一团糟。然后我尝试将上面的内容更改为指针,并在更改其他所有内容以处理指针之后,我的代码根本不会输出。 :(
猜你喜欢
  • 2013-03-05
  • 2014-11-05
  • 2019-11-16
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
相关资源
最近更新 更多