Поиск повторяющегося узла в пользовательском LinkedList вызывает ошибку сегментации рекурсией

#c #linked-list #segmentation-fault

#c #связанный список #ошибка сегментации

Вопрос:

Введение

Я пытаюсь создать LinkedList с узлами, которые хранят значение и указатель на следующий

Как я это делаю?

Я использую эту функцию

 /*
    Finds if two Nodes contain the same value
*/

void findRepeated(Node *node) {

Node *nodeList = node; //node List

int currentValue; //stores the value of nodeList
int nextValue; //stores value from nextNode

//Skip the current value
currentValue = nodeList->value; //Current value of the List
nodeList = nodeList->next; //Next node

//Keep going till the end of the list (NULL)
while(nodeList != NULL) {
    
    nextValue = nodeList->value; //Get the next value from the Nodelist
    
    printf("Testing %d with %dn", currentValue, nextValue);
    //Check if currentValue equals nextValue
    if (currentValue == nextValue) {
        printf("%d is repeated in the Listn", currentValue);
        return; //Exit function
    }
    //Goto next node in List
    nodeList = nodeList->next; //Next node
}
findRepeated(node->next); //Recursion
}
  

который использует магию рекурсии, чтобы найти его, и делает это правильно, используя этот основной код

 insertNode(amp;head, 0);
insertNode(amp;head, 1);
insertNode(amp;head, 2);
insertNode(amp;head, 3);
insertNode(amp;head, 4);
insertNode(amp;head, 0);    
findRepeated(head);
//printList(head); 
  

но затем, когда я пытаюсь «автоматизировать» его в цикле выполнения, возникает ошибка сегментации, и я не могу понять, почему

Полный код

 //This is an element obj for the List
typedef struct Node {
    int value; //Value of the node
    struct Node *next; //Next element in List pointer
} Node;

/*
 Insert a node into the List
*/
void insertNode(struct Node** head, int value) {

    //Allocate memory to new Node
    struct Node* new_node = (Node*)malloc(sizeof(Node));

    //Add the data to the new node
    new_node->value = value; //The value
    new_node->next = *head; //The pointer to next Node

    (*head) = new_node;
}

/*
    Prints all the values stored in the List 
*/
void printList(Node *node) {
    //'till we don't find a NULL (end point) we keep going
    while (node != NULL){
        printf(" %d ", node->value); //Print the value of the node
        node = node->next; //Move the pointer to the next, till you find a NULL
    }
}

/*
    Finds if two Nodes contain the same value
*/
void findRepeated(Node *node) {

    Node *nodeList = node; //node List
    
    int currentValue; //stores the value of nodeList
    int nextValue; //stores value from nextNode

    //Skip the current value
    currentValue = nodeList->value; //Current value of the List
    nodeList = nodeList->next; //Next node
    
    //Keep going till the end of the list (NULL)
    while(nodeList != NULL) {
        
        nextValue = nodeList->value; //Get the next value from the Nodelist
        
        printf("Testing %d with %dn", currentValue, nextValue);
        //Check if currentValue equals nextValue
        if (currentValue == nextValue) {
            printf("%d is repeated in the Listn", currentValue);
            return; //Exit function
        }
        //Goto next node in List
        nodeList = nodeList->next; //Next node
    }
    findRepeated(node->next); //Recursion
}

//Function definitions goes above their calls
int main()
{
    int d;
    //Create empty List
    struct Node* head = NULL;

    insertNode(amp;head, 0);
    
    do {

        printf("Input an Integer: ");
        scanf(" %d", amp;d);
        printf("Input was: %dn", d);
        
        insertNode(amp;head, d);
        
        printf("Input done. Printing list...n");
        printList(head);
        printf("Fetching repeated...n");
        
        findRepeated(head); //segmentation fault...

    } while (1 == 1);
    


    
    //Insert some nodes
/*    
    insertNode(amp;head, 0);
    insertNode(amp;head, 1);
    insertNode(amp;head, 2);
    insertNode(amp;head, 3);
    insertNode(amp;head, 4);
    insertNode(amp;head, 5);    
    findRepeated(head);
    //printList(head);
*/    
    
    
}
  

Я хотел бы знать, ПОЧЕМУ это происходит и КАК я могу это исправить.

Ответ №1:

findRepeated сбой функции в строке, в которой вызывается рекурсия:

 findRepeated(node->next);
  

Потому что вы не проверяете, равно ли значение node NULL . Поэтому, когда вы переходите к последнему узлу, вы вызываете функцию findRepeated с node->next where next равно null .
Чтобы исправить это, вам просто нужно проверить это следующим образом:

 if (node->next != NULL) {
    findRepeated(node->next);
}
  

Комментарии:

1. Кстати, если бы я хотел работать со строками вместо целых чисел. Действительно ли мне нужно слишком сильно менять то, что у меня есть?