Операции со связанным списком в C (ошибка сегментации выгружена из памяти!) - PullRequest
1 голос
/ 16 октября 2019

Я пытался реализовать операции связанного списка в c с прошлых нескольких дней, но я продолжаю сталкиваться с той же самой ошибкой снова и снова, которая говорит: «Ошибка сегментации ядра сброшена». Я не могу понять, какая часть логики идет не так. Это странно, поскольку после устранения всех предупреждений и ошибок код просто не выполняется. Было бы также хорошо, если бы кто-то указал мне, правильно ли я использую связанный список и указатели. Мой код кажется огромным для публикации, но я просто не смог его сократить. И еще раз, я был бы благодарен всем тем, кто может помочь мне и сделать этот код более читабельным и уменьшить двусмысленность.

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

struct nodes 
{
    int data;
    struct nodes* next; 
};
typedef struct nodes* node;
node head=NULL;
void InsertFront()
{
    node temp=NULL;
    printf("Enter The Value Of Node\n");
    scanf("%d",&temp->data);
    if(head==NULL)
    {
        head->data=temp->data;     
    }
    else
    {
        temp->next=head;
        head=temp;
    }
}

void InsertBack()
{
    node temp,newnode;
    printf("Enter The Value Of Node\n");`enter code here`
        scanf("%d",&newnode->data);
    if(head==NULL)
    {
        head->data=newnode->data;
    }
    else
    {
        temp=head;
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        newnode=temp->next;
    }    
}

void InsertPosition()
{
    node previousnode,newnode,nextnode,temp;
    int position,count=0;
    printf("Enter the Position At Which New Node Has To Be Inserted");
    scanf("%d",&position);
    printf("Enter The Value Of Node\n");
    scanf("%d",&newnode->data);
    if(head==NULL)
    {
        head->data=newnode->data;
    }
    else
    {
        temp=head;
        while(temp->next!=NULL && count<position);
        {
            previousnode=temp;
            temp=temp->next;
            count=count+1;
            nextnode=temp;
        }
        previousnode->next=newnode;
        newnode->next=nextnode;
    }
}

void DeleteFront()
{
    node temp;
    if(head->next==NULL)
    {
        head==NULL;
    }
    else
    {
        head->next=temp;
        head=NULL;
        head=temp;
    }
}

void DeleteBack()
{
    node temp;
    if(head->next==NULL)
    {
        head==NULL;
    }
    else
    {
        temp=head;
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        temp=NULL;
    }
}

void DeletePosition()
{
    node temp,nextnode,deletenode;
    int position,count=0;
    printf("Enter The Position At Which The Node Has To Be Deleted");
    scanf("%d",&position);
    if(head->next==NULL)
    {
        head==NULL;
    }
    else
    {
        temp=head;
        while(temp->next!=NULL && count!=position)
        {
            temp=temp->next;
            count=count+1;
        }
        deletenode=temp->next;
        nextnode=deletenode->next;
        deletenode->next=NULL;
        temp->next=nextnode;
    }
}

void Display()
{
    node temp;
    temp=head;
    if(head==NULL)
    {
        printf("Linked List Seems To Be Empty");
    }
    while(temp->next!=NULL)
    {
        printf("%d -> ",temp->data);
    }

}

int main()
{ 
    int choice;
    printf("\nLINKED LIST OPERATIONS\n\n");
    printf("Select An Option\n1 - Insert From Front\t   2 - Insert From Back\n3 - Insert At 
            A Position   4 - Delete At The Front\n5 - Delete At The Back\t   6 - Delete At A 
            Position\n7 - Display\t           8 - Exit\n\n");
    scanf("%d",&choice);
    switch(choice)
    {
        case(1) :
            {
                InsertFront();
            }
        case(2) :
            {
                InsertBack();
            }
        case(3) :
            {
                InsertPosition();
            }
        case(4) :
            {
                DeleteFront();
            }
        case(5) :
            {
                DeleteBack();
            }
        case(6) :
            {
                DeletePosition();
            }
        case(7) :
            {
                Display();
            }
        case(8) :
            {
                exit(0);
            }
        default :
            {
                printf("Invalid Input\n");
                exit(0);
            }

    }
}

1 Ответ

0 голосов
/ 17 октября 2019

С манжеты, ваша первая функция, вы можете захотеть передать указатель на голову в качестве аргумента функции или иметь возвращаемое значение в виде узла *, чтобы она была более универсальной. Ни head, ни temp не были инициализированы, что происходит тремя способами: вы присваиваете указатель существующему адресу переменной, вы делаете вызов malloc для назначения хранилища, и третьим способом, который я не помню, ознакомьтесь с ресурсами ниже. Они помогут! Вы выделили переменную-указатель, объявив локальный и глобальный узел *, они совместимы, однако вы не инициализировали ни одну из них со ссылкой на другую переменную;Вы просто объявили их. Указатель должен быть инициализирован с присвоением ссылки на другой адрес либо из malloc, & addressof и т. Д. Null просто помечает их как плохие указатели, не бросая сегфофт при тестировании. Думайте об этом как об имени файла без выделенного хранилища ... Вы не можете сохранить его, но оно там. Поскольку ни одна из них не инициализирована, при попытке назначить их вы получаете ошибку памяти, потому что ни одно хранилище еще не было выделено. Что значит ... сегфо! Поверхностно существует три компонента указателя: [Адрес указателя для псевдонима / именованной области памяти / объекта | блок памяти, зарезервированный для хранения любого размера, который вы объявляете, который вам необходим, в этом случае вы оставляете его таким, как таковой: head = malloc (sizeof (struct node *)), это, скорее всего, выделяет 8-байтовое адресное пространство, которое указывает подходящую область памяти-> | * разыменованное значение адреса, на который ссылается хранилище] Попробуйте запустить gdb и установить разрыв для каждого издва указателя в вашей первой функции. Я надеюсь, что это помогает, и надеюсь, что я не дал вам плохих советов ...

Я слишком много боролся с этим, вот несколько хороших ресурсов, которые будут стоить вашего времени:

Библиотека Stanfor CS -CONCISELY охватывает указатели, связанные списки, двоичные деревья, отладку, чтобы точно определить, какая строка кода генерирует вашу ошибку;http://cslibrary.stanford.edu/

...