Miranda Miranda - 2 months ago 93
C Question

Why does this segfault?

Program received signal SIGSEGV, Segmentation fault.
0x08048637 in insertWordDictR (string=0xbf87e7b6 "a", child=0x20f88,
isTerminal=0x20f8c) at dictionary.c:54
54 *isTerminal = False;


in the header file I have

typedef enum {False, True} bool;


Here are the related lines of code:

dictLink insertWordDictR(char *string, dictLink child, bool* isTerminal){
dictLink newWord;

if(isTerminal != NULL){
if(string[0] == '\0'){
*isTerminal = True;
return NULL;
}else{
*isTerminal = False;
}
}


if (child == NULL){
newWord = malloc(sizeof (struct dictEdge));
newWord->thisChar = string[0];
newWord->child = insertWordDictR(string + 1, newWord, &(newWord->isTerminal));
newWord->sibling = NULL;
}else{
newWord = insertIntoSiblingList(string, child);

}

return newWord;
}


This line is an example of how I called this function

newWord->child = insertWordDictR(string + 1, newWord, &(newWord->isTerminal));


All files can be found here, there is also an input file called "testing".

Answer Source

In this sequence you are taking the address of a field from an uninitialized pointer, as indicated by the inserted comment:

dictLink result;
if(sibling == NULL){
      result = malloc(sizeof (struct dictEdge));
      result->thisChar = string[0];
      result->sibling = NULL;
      result->child = insertWordDictR(string + 1, result, &(result->isTerminal)); 

}else if(string[0] < sibling->thisChar){
      result = malloc(sizeof (struct dictEdge));
      result->thisChar = string[0];
      result->sibling = sibling;
      result->child = insertWordDictR(string + 1, result, &(result->isTerminal));  

  }else if(string[0] == sibling->thisChar){
      /* "result" has not been initialized, &(result->isTerminal) is an invalid pointer */
      sibling->child = insertWordDictR(string + 1, result, &(result->isTerminal)); 
    result = sibling;