Нарушение на достъпа до свързан списък

Получавам тази грешка по време на изпълнение.

Виждате, че имах free(temp) преди изразите cout‹‹. Премахнах ги. Мислех, че е поради лошо дерефериране, което се оказа нещо повече.

Това е моята програма:

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>

using namespace std;

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

node* head=NULL;
node* current=NULL;

void insert_node()
{
    int num=0;
    cout<<"\nEnter the value of the node to insert\n:";

    cin>>num;

    if(head==NULL)
    {
        head=(node*)malloc(sizeof(*head));
        //current=(node*)malloc(sizeof(*current));
        head->data=num;
        head->next=NULL;
        current=head;
        cout<<"Created list\n";

    }
    else
    {
        node* temp=(node*)malloc(sizeof(*temp));
        temp->data=num;
        temp->next=NULL;
        current->next=temp;
        current=temp;
        cout<<"Added element\n";
        free(temp);
        cout<<"dereferenced element\n";

    }
}

void delete_node()
{

    if(head!=NULL && head->next==NULL  )//only one node
    {

        current=head=NULL;
        cout<<"Deleted Head\n";
    }
    else if(head!=NULL && head->next!=NULL)//>= 2 nodes
    {
       node* temp;
       //temp=NULL;
       temp=head;
       while(temp->next!=current)
       {
           temp=temp->next;
       }
       temp->next=NULL;
       current=temp;
       cout<<"Deleted last element\n";
      // free(temp);
       cout<<"Dereferenced temp\n";
    }
    else
    {
        cout<<"delete was not performed";
    }
}

void list_linked_list()
{
    node* temp=(node*)malloc(sizeof(* temp));

    temp=head;

    while(temp!=NULL)
    {

        cout<<temp->data<<"->";
        temp=temp->next;

    }
    cout<<"displayed list\n";
    //free(temp);
    cout<<"dereferenced temp";
}

void search_node()
{
    cout<<"\nenter a number to search";
    int search=0,found=0;
    cin>>search;

    node* temp=(node*)malloc(sizeof(* temp));
    temp=head;
    while(temp!=NULL)
    {
        if(temp->data==search)
            found=1;
    }
    if(found==1)
        cout<<"found\n";
    else
    cout<<"not found\n";
    //free(temp);
    cout<<"dereferenced temp";
}


void main()
{

    int n=0;
    k:
    cout<<"Linked List operations: \n1. insert \n2. delete \n3. search\n 4. view List \n5. Exit";
    cin>>n;

    switch(n)
    {
    case 1: insert_node();break;

    case 2: delete_node();break;

    case 3: search_node();break;

    case 4: list_linked_list();break;
    case 5: exit(0);break;
    default: cout<<" Please enter valid number between 1 and 5";
            break;

    }
    goto k;
}

Не мисля, че съм разбрал погрешно концепцията за свързан списък. Доста ясно ми е. Мисля, че има грешка с показалеца.

Благодаря ти.

РЕДАКТИРАНЕ: НОВ КОД:

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

struct node* head=NULL;
struct node* current=NULL;





void insert_node()
{
    int num=0;
    cout<<"\nEnter the value of the node to insert\n:";

    cin>>num;

    if(head==NULL)
    {

        head->data=num;
        head->next=NULL;
        current=head;
        cout<<"Created list\n";

    }
    else
    {
        struct node* temp=(node*)malloc(sizeof(node));
        temp->data=num;
        temp->next=NULL;
        current->next=temp;
        current=temp;
        cout<<"Added element\n";
        cout<<"dereferenced element\n";

    }


}

void delete_node()
{

    if(head!=NULL && head->next==NULL  )//only one node
    {

        current=head=NULL;   //Am I supposed to do anything else here??
        cout<<"Deleted Head\n";
    }
    else
    if(head!=NULL && head->next!=NULL)//>= 2 nodes
    {
       struct node* temp=(node*)malloc(sizeof(node));;
       //temp=NULL;
       temp=head;
       while(temp->next!=current)
       {
           temp=temp->next;
       }
       temp->next=NULL;
       current=temp;
       cout<<"Deleted last element\n";
      free(temp->next);
       cout<<"Dereferenced temp\n";
    }
    else
    {
        cout<<"delete was not performed";
    }


}

void list_linked_list()
{
    node* temp=(node*)malloc(sizeof(node));

    temp=head;

    while(temp!=NULL)
    {

        cout<<temp->data<<"->";
        temp=temp->next;

    }
    cout<<"displayed list\n";
    //free(temp);              //should I free temp?
    cout<<"dereferenced temp";
}

void search_node()
{
    cout<<"\nenter a number to search";
    int search=0,found=0;
    cin>>search;

    node* temp=(node*)malloc(sizeof(node));
    temp=head;
    while(temp!=NULL)
    {
        if(temp->data==search)
            found=1;
        else
            temp=temp->next;
    }
    if(found==1)
        cout<<"found\n";
    else
    cout<<"not found\n";
    free(temp);          //shoudl I free temp?
    cout<<"dereferenced temp";
}

person LoveMeow    schedule 06.09.2013    source източник
comment
Трябва да освободите възлите, когато изтриете възел. Не и когато вмъкнете възел.   -  person    schedule 06.09.2013
comment
Не използвайте free(temp) в insert_node(). Той променя мястото в паметта, посочено от текущото като недостъпно.   -  person Don't You Worry Child    schedule 06.09.2013
comment
Защо етикетът C? Това е C++ код.   -  person andyn    schedule 06.09.2013


Отговори (2)


Има множество проблеми във вашия код:

  1. Вие free() създавате възел във вашата функция за вмъкване, което не е това, което искате. Така че премахнете реда free(temp) от вашата функция за вмъкване.

  2. Вие наистина искате да освободите възела, когато изтриете елемент от вашия свързан списък. Така че разкоментирайте реда: free(temp);. Но това не е правилният current възел, който искате да освободите(). Тук temp е вашият нов current, докато искате да освободите () стария си current, който temp->next. Така че вашият оператор free() трябва да бъде: free(temp->next); в delete_node() функция (не free(temp);).

  3. Върнатата стойност на main трябва да е int.

  4. Ако използвате C++, има по-добри начини за внедряване на свързани списъци. Може да искате да използвате new и delete вместо malloc и free. Използвайте C++ заглавки вместо C заглавки.

  5. Ако използвате C, тогава не прехвърляйте стойността, върната от malloc в C.

  6. Използвате goto като заместител на цикъл, който е ненужен, когато можете просто да използвате for(;;) { } или while(1) { }.

person P.P    schedule 06.09.2013
comment
Поздравления за 20K RP!! :) - person Grijesh Chauhan; 06.09.2013
comment
Промених всичко, което споменахте. Сега, когато вмъкна елемент, той казва нарушение на достъпа или просто се забива - person LoveMeow; 06.09.2013
comment
@RamapriyaSridharan Не съм сигурен дали сте направили точно това, което споменах. След модифициране на вашия код работи добре, както е показано тук: codepad.org/WKjUquaH - person P.P; 06.09.2013
comment
Благодаря ти! Така че сбърках концепцията си за указател. Трябва да попитам. Кога точно използвате malloc? Не го използвам за текущия указател. Но инициализирах главата с ток глобално, така че защо динамично разпределяне на m/y за глава? - person LoveMeow; 06.09.2013
comment
@RamapriyaSridharan 1. Should I free temp? Не, вие не извиквате free() другаде освен delete_node() функция. 2. //Am I supposed to do anything else here?? Да, трябва да free() този възел (само един случай на възел) преди да го настроите на NULL. т.е. free(current); head=current=NULL; - person P.P; 06.09.2013
comment
@RamapriyaSridharan Това са много въпроси;) Трябва да изучите добра книга за C и по-специално за указатели. head е само указател и не сочи към никаква валидна памет, където може да съхранява структурните данни. Следователно, трябва да използвате malloc, за да разпределите памет. - person P.P; 06.09.2013

В другата част на функцията за вмъкване вие ​​освобождавате нов възел веднага след като го добавите в свързан списък, което причинява недефинирано поведение по време на изпълнение:

  else
    {
        node* temp=(node*)malloc(sizeof(*temp));
        temp->data=num;
        temp->next=NULL;
        current->next=temp;
        current=temp;
        cout<<"Added element\n";
        free(temp);    <------"Bug"
        cout<<"dereferenced element\n";    
    }

Забележка: Не можете да получите достъп до възел, за който паметта е освободена (free()), извършването на това е незаконна операция. Трябва да освободите памет за възел, когато приключите с програмата (и нямате нужда от достъп до тази памет отново).

person Grijesh Chauhan    schedule 06.09.2013
comment
Благодаря ти. Промених тази грешка, все още получавам грешка за нарушение на достъпа. - person LoveMeow; 06.09.2013
comment
@RamapriyaSridharan Добавете нов код към въпроса си или повдигнете нов въпрос. - person Grijesh Chauhan; 06.09.2013