什么导致分段错误?

时间:2014-03-27 23:13:25

标签: c pointers recursion

我正在编写代码,以递归方式打印出链接在一起的节点的字符。这些节点链接在一起创建一个“map”(只是从struct到其他节点的指针)。结构如下实现:

typedef struct Node *node_ptr;

struct Node{
   char ch;
   node_ptr firstPtr;
   node_ptr secondPtr;
   node_ptr thirdPtr;
};

现在,我需要打印出x节点的步骤。我从控制台获取此值,该控制器存储在int变量中并将其传递给函数。我也将指针传递给Node。此功能实际打印出正确的输出,但是有两个小错误。

例如,我有一个节点我叫“A”。 “A”的ch字段是'A',每个节点我有ch字段将是我称之为节点的指针以使其简单。我想要的一个简单示例如下:

节点A:

   ch -> 'A'; 
   A->firstPtr = B;   
   A->seondPtr = NULL; 
   A->thirdPtr = NULL;

节点B:

   ch = 'B'. 
B->firstPtr = A;
B->secondPtr = C;
B->thirdPtr = F;

因此,如果我用户输入A并且距离为2,则应打印出:B,C,F。

我写的递归函数做了这个,但也打印出A.这很可能是因为B也指向A并且它也打印出来,但我认为我处理了这种情况,它仍然会这样做。另外,它在程序结束时给出了分段错误,我也不确定为什么。这是递归函数:

 void print_levels(int dist, node_ptr aNode){
if(dist == 0){
// if int is zero, do nothing we are done. 
}
else{
    /*
    if there is pointer (doesn't point to NULL) and if the Node it's pointing
    to does not have the same "ch" as the current Node.  
    */
    if(aNode->firstPtr && !(aNode->firstPtr->ch == aNode->ch)){
        printf("%c\n", aNode->firstPtr->ch);
    }
    if(aNode->secondPtr && !(aNode->secondPtr->ch == aNode->ch)){
        printf("%c\n", aNode->secondPtr->ch);
    }
    if(aNode->thirdPtr && !(aNode->thirdPtr->ch == aNode->ch)){
        printf("%c\n", aNode->thirdPtr->ch); 
    }
    print_levels(dist-1, aNode->firstPtr);
    print_levels(dist-1, aNode->secondPtr);
    print_levels(dist-1, aNode->thirdPtr);      
}
}

我要问的是为什么在我给出的示例中,它还打印出A,为什么会导致分段错误?我是C的新手,并且事先欣赏所有的帮助和见解。

3 个答案:

答案 0 :(得分:1)

你打电话:

print_levels(dist-1, aNode->firstPtr);
print_levels(dist-1, aNode->secondPtr);
print_levels(dist-1, aNode->thirdPtr);   

如果aNode->firstPtr等等为NULL,您应该在每个之前检查:

if (aNode->firstPtr != NULL)
    print_levels(dist-1, aNode->firstPtr);
if (aNode->secondPtr != NULL)
    print_levels(dist-1, aNode->secondPtr);
if (aNode->thirdPtr != NULL)
    print_levels(dist-1, aNode->thirdPtr);   

或者检查print_levels aNode是否为NULL并返回:

void print_levels(int dist, node_ptr aNode){
  if (dist == 0 || aNode == NULL){

答案 1 :(得分:1)

1)打印出A的原因是,一旦递归调用print_levels()aNode将引用当前节点而不是前一节点。由于图表中有一个周期,因此打印出A:一旦aNode为B,aNode->为'B',因此aNode->firstPtr->ch为'A'并打印,因为它不等于'B'。如果要避免打印初始节点,可以将其他字符传递给print_levels函数并检查它是否相等。

2)分段错误是一个运行时错误,如果没有看到所有代码,则更难以进行二次转换。我建议您在调试器(例如gdb)中运行代码,并找出错误发生的位置(堆栈跟踪)。正如breakfoot在评论中建议的那样,确保所有变量在使用前都已初始化。尤其要确保aNode不是NULL(aNode && aNode->firstPtr && !(aNode->firstPtr->ch == aNode->ch)),否则访问aNode->firstPtr是未定义的行为。

答案 2 :(得分:0)

我认为链表中存在循环,导致分段错误。 A指向B,B再指向A,依此类推。你应该实现一些东西来避免循环。