Получение ошибки SIGSEGV. Не могу найти указатель ответственный - PullRequest
0 голосов
/ 30 июня 2019

Я только начал изучать связанные списки в C, и я, кажется, получаю бесконечный цикл в части печати, пытался исправить все свободные концы, все еще застрявшие с той же проблемой. Я пытался отладить несколько раз, и это всегда ошибка SIGSEGV. Я использовал DEV C ++ и GCC 4.9.2.

#include<stdio.h>
#include<stdlib.h>

typedef struct node {
    int data;
    struct node *next;
}node;

void print();
node *clist(int n);
node *head = NULL;

int main() 
{
    int n;
    printf("Input the number of nodes for the Linked List.\n");
    scanf("%d", &n);

    clist(n);
    print();

    return 0;
}

void print() 
{
    node *show = NULL;
    show = head;
    while (show != NULL) {
        printf("%d => ", show->data);  
        show = (show->next);
    }

    printf("NULL");

}

node *clist(int n) 
{
    node *temp = NULL;
    node *p = NULL;
    int i;

    for (i = 0; i<n; i++)
    {
        temp = (node*)malloc(sizeof(node));

        printf("Enter the element %d of the list", i + 1);
        scanf("%d", &temp->data);

        if (head == NULL)
        {
            head = temp;

        }

        else { 
      p = head; 
      while( p->next ) 
           { 
              p = p->next; 
            } 
            p->next = temp; //UPDATE: SIGSSEGV ERROR HERE NOW 
            }
              }
    return head;
}

Ответы [ 2 ]

0 голосов
/ 30 июня 2019

Я изменил ваш код и добавил пояснительные комментарии в строке:

node *clist(int n)
{
    node *temp = NULL;
    node *p = NULL;
    node *prePtr=NULL; //define this to keep track of previous node
    int i;

    for (i = 0; i<n; i++)
    {
        temp = (node*)malloc(sizeof(node));

        printf("Enter the element %d of the list", i + 1);
        scanf("%d", &temp->data);
        //temp->next=NULL;
        if (head == NULL)
        {
            head = temp;
            head->next=NULL; //Make head OR above Temp next pointer NULL
        }

        else {
      p = head;
      //while( p->next ) This is not condition
        while( p!=NULL )//Check for a condition that became false eventually.
        {
               prePtr=p;//to keep track of the previous location
                        //because you cannot add another node if you are 
                        //already ahead of that node.
              p = p->next;//this make you ahead of the node where you want
                         //to insert node when wile condition became false.
            //}
        }
            //p->next = temp; //UPDATE: SIGSSEGV ERROR HERE NOW
            //above line try to add a node on next while it's already NULL.
                prePtr->next=temp;//this take previous node and add a temp to its next node
                temp->next=p;//here you assign temp->next=p which is NULL
            }
    }
    return head;
}
0 голосов
/ 30 июня 2019

следующий предложенный код:

  1. чисто компилирует
  2. выполняет желаемую функциональность
  3. правильно проверяет и обрабатывает ошибки
  4. последовательно с отступом
  5. убирает за собой
  6. позволяет избежать избыточности в таких выражениях, как: if( head == NULL )
  7. исключает неиспользованные возвращаемые значения
  8. правильно объявляет прототипы функций, которые не принимают параметров
  9. для удобства чтения, использует соответствующий горизонтальный интервал

и теперь предложенный код:

#include <stdio.h>
#include <stdlib.h>

typedef struct snode
{
    int data;
    struct snode *next;
} node;

// prototypes
void  print( void );
void  clist( int n );
void  cleanup( void );

node *head = NULL;


int main( void )
{
    int n;

    printf( "Input the number of nodes for the Linked List.\n" );
    if( scanf( "%d", &n ) != 1 )
    {
        fprintf( stderr, "scanf for number of data points failed\n" );
        exit( EXIT_FAILURE );
    }

    clist( n );
    print();
    cleanup();
    return 0; // << optional in modern C
}


void print()
{   
    node *show = head;

    while( show )
    {
        printf( "%d => ", show->data );
        show = show->next;
    }

    puts( "" );
}


void clist( int n )
{
    node *temp = NULL;
    node *p = NULL;

    for( int i=0; i<n; i++ )
    {
        temp = malloc( sizeof( node ) );
        if( !temp )
        {
            perror( "malloc failed" );
            cleanup();
            exit( EXIT_FAILURE );
        }

        // EDIT:
        temp->next = NULL;
        // end EDIT:

        printf( "Enter the element %d of the list", i+1 );
        if( scanf( "%d", &temp->data ) != 1 )
        {
            fprintf( stderr, "scanf for a data failed\n" );
            cleanup();
            exit( EXIT_FAILURE );
        }

        if( !head )
        {  // list empty
            head = temp;
        }

        else
        {  // list already contains some nodes
            p = head;

            while( p->next )
            {
                p = p->next;
            }
            p->next = temp;
        }
    }
}


void cleanup()
{
    node *temp = head;
    node *current;

    while( temp )
    {
        current = temp;
        temp = temp->next;
        free( current );
    }
}

Вот результат простого запуска программы:

Input the number of nodes for the Linked List.
2
Enter the element 1 of the list1
Enter the element 2 of the list2
1 => 2 => 

Предложить поставить пробел перед пользовательским вводом для значения данных узла в выходных данных

...