收到SIGSEGV错误。不能找到负责的指针

时间:2019-06-30 17:14:48

标签: c data-structures linked-list sigsegv

我刚刚开始研究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 :(得分:0)

以下建议的代码:

  1. 干净地编译
  2. 执行所需的功能
  3. 正确检查并处理错误
  4. 始终缩进
  5. 自行清理
  6. 避免在诸如if( head == NULL )
  7. 的语句中出现冗余
  8. 消除未使用的返回值
  9. 正确声明不带参数的函数原型
  10. 为便于阅读,请使用适当的水平间距

现在,建议的代码:

#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 => 

建议在用户输入之前为输出中的节点数据值放置一个空格

答案 1 :(得分:0)

我已经修改了您的代码,并在以下行中添加了解释性注释:

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