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

Я получаю эту ошибку во время выполнения.

Видите ли, у меня был 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? Это код С++.   -  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
Поздравляю с 20К 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? Я не использовал его для указателя current. но я инициализировал head с текущим глобально, так зачем динамически выделять 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 функции вставки вы освобождаете новый узел сразу после добавления его в связанный список, что вызывает неопределенное поведение во время выполнения:

  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