首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归呼叫分段故障问题

递归呼叫分段故障问题
EN

Stack Overflow用户
提问于 2013-10-21 07:11:47
回答 3查看 113关注 0票数 0

再问一次快速问题。我正在创建一个递归函数,它将查找“源”规则数组中的元素,并在“源”规则类型与目标字符相同的情况下将这些规则应用于“目标数组”。此外,该函数检查目标字符是否在符号数组中,如果不在,则添加它(并在新应用的规则上抛出一些标志)。这都是由一个递归调用驱动的,它使用一个计数器来确定经过了多少次迭代,并用来确定应该应用新规则的目标数组中的点,所以我们不会覆盖它。

我也放了一些调试代码来显示结果。

下面是函数本身:

代码语言:javascript
复制
//Recursively tack on any non terminal pointed elements 
int recursiveTack(rule * inrule[], char target, rule * targetrule[],
        int counter, char symbols[])
{

    printf("Got into recursiveTack\n");
    printf("target is %c\n", target);
    printf("counter is %d", counter);

    for (int k = 0; k < sizeof(inrule); k++)
    {

        if (inrule[k]->type == target)
        {

            //doublecheck to see if we're trying to overwrite
            if (targetrule[counter]->used = true)
            {
                counter++;
            }

            targetrule[counter]->head = inrule[k]->head;
            targetrule[counter]->type = inrule[k]->type;
            targetrule[counter]->used = true;

            //Check to see if the elements are new to the symbols table and need to be added
            if (!contains(returnGotoChar(targetrule[counter]), symbols))
            {

                //If not then add the new symbol
                addChar(returnGotoChar(targetrule[counter]), symbols);
                //Also set the goto status of the rule
                targetrule[counter]->needsGoto = true;
                //Also set the rule's currentGotoChar
                targetrule[counter]->currentGotoChar = returnGotoChar(
                        targetrule[counter]);
            }

            counter++;

            //recursivly add elements from non terminal nodes
            if (isNonTerm(targetrule[counter]))
            {
                char newTarget = returnGotoChar(targetrule[counter]);
                counter = recursiveTack(inrule, newTarget, targetrule, counter,
                        symbols);
            }
        }
    }

    //return how many elements we've added
    return counter;
}

电话是这样的:

代码语言:javascript
复制
if(isNonTerm(I[i+first][second]))
{
    printf("Confirmed non termainal\n");
    printf("Second being passed: %d\n", second);
    //Adds each nonterminal rule to the rules for the  I[i+first] array
    second = recursiveTack(I[i], targetSymbol, I[i+first], second, symbols[first]);
}

在此之前,所有传入的数组都已初始化。然而,我得到的输出表明,递归在离开地面之前在某个地方被终止了。

输出:

代码语言:javascript
复制
Second being passed: 0
Confirmed non termainal
Got into recursiveTack
target is E
Segmentation fault

任何帮助都是很好的,如果需要的话,我也有程序的其余部分可用,它大约有700行,包括注释。我很确定这只是另一个遗漏了一些简单的东西的案例,但请让我知道你的想法。

EN

回答 3

Stack Overflow用户

发布于 2013-10-21 07:24:29

代码语言:javascript
复制
for(int k = 0; k < sizeof(inrule); k++)

sizeof(inrule)将返回指针类型的大小(4或8)。可能不是你想要的。如果要使用这些类型的结构,还需要将数组的大小作为参数进行传递。

不过,使用像std::vector这样的标准库容器会更好。

票数 1
EN

Stack Overflow用户

发布于 2013-10-21 07:15:34

代码语言:javascript
复制
if(targetrule[counter]->used = true){
 counter++;
  }

//怎样保证targetrulecounter是有效的?你能在它之前和之后做一次printf调试吗?

票数 0
EN

Stack Overflow用户

发布于 2013-10-21 07:35:30

我在这里看到的最大的事情是:

代码语言:javascript
复制
for(int k = 0; k < sizeof(inrule); k++)

这不会像你想的那样。inrule是一个指针数组,因此sizeof(inrule)将是元素的数量* sizeof(rule*)。这可能很快就会导致数组的末尾耗尽。

尝试将其更改为:

代码语言:javascript
复制
for (int k = 0; k < sizeof(inrule) / sizeof(rule*); ++k)

您还可以考虑在print语句之后添加fflush(stdout);。当一些输出仍然被缓冲时,你就崩溃了,所以它很可能隐藏了崩溃发生的地方。

编辑:

那行不通的。如果你有一个函数做类似这样的事情:

代码语言:javascript
复制
int x[10];
for (int i = 0; i < sizeof(x) / sizeof(int); ++i) ...

它可以工作,但在函数调用的另一端,类型降级为int*,并且sizeof(int*)与sizeof(int10)不同。你要么需要通过尺寸,要么..。更好的是,使用向量而不是数组。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19483964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档