user3268401
user3268401

Reputation: 329

What is causing segmentation fault?

I am writing code that recursively prints out characters of Nodes that are linked together. These nodes are are linked together create a "map" (simply just pointers from the struct to other nodes). The structure is implemented as followed:

typedef struct Node *node_ptr;

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

Now, I need to print out how the nodes that are x steps way. I get this value from the console that I store in an int variable and pass it it to a function. I also pass a pointer to a Node as well. This function actually prints out the correct outputs, but for two small errors.

For example, I have a Node I call "A". The ch field of "A" is 'A' and every Node I have the ch field will be the letter I call the pointer to the Node to make it simple. A simple example I want is the following:

Node A:

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

Node B:

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

So, if I user enters A and the distance away to be 2, it should print out: B, C, F.

The recursive function I wrote does this, but also prints out A. This is most likely because B also points to A and it printed that out as well, but I think I handle that case and it still does it. In addition, it gives a segmentation fault at the end of the program and I'm not sure why as well. Here is the recursive function:

 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);      
}
}

What I am asking is why does it in the example I gave about, it also print out A and why does this cause a segmentation fault? I am relatively new to C and appreciate all the help and insight beforehand.

Upvotes: 0

Views: 93

Answers (3)

Vinay Tiwary
Vinay Tiwary

Reputation: 305

I think there are loops in your linked list and that causes the segmentation fault. A is pointing to B and B again points to A and so on. You should implement something to avoid loops.

Upvotes: 0

jev
jev

Reputation: 2013

1) The reason A is printed out is that once you recursively call print_levels(), aNode refers to the current node and not to the previous node. A is printed since there is a cycle in the graph: once aNode is B, aNode-> is 'B' , hence aNode->firstPtr->ch is 'A' and is printed because it is not equal to 'B'. If you want to avoid printing the initial node you could pass an additional character to the print_levels function and check equality with it.

2) Segmentation fault is a run time error which is more difficult to dianose without seeing all of the code. I'd suggest you run the code in a debugger (e.g. gdb) and find out where exactly the error happens (stack trace). As brokenfoot suggests in the comment ensure that all variables are initialised before use. In particular make sure aNode is not NULL: (aNode && aNode->firstPtr && !(aNode->firstPtr->ch == aNode->ch)), otherwise accessing aNode->firstPtr is undefined behaviour.

Upvotes: 1

CMoi
CMoi

Reputation: 846

You call:

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

You should either check before each if aNode->firstPtr, etc is 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);   

Or check in print_levels if aNode is NULL and just return:

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

Upvotes: 1

Related Questions