Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kolejka wykolejona po usunięciu elementu

Ostatnio zmodyfikowano 2017-03-29 20:22
Autor Wiadomość
witeks44
Temat założony przez niniejszego użytkownika
Kolejka wykolejona po usunięciu elementu
» 2017-03-28 09:53:16
Witam,
kłopot mojej kolejki polega na tym, że po usunięciu ostatniego elementu i dodaniu kolejnych, program wyrzuca mi:
Exception thrown: read access violation.
pom was 0xDDDDDDDD.
Problem pojawia się tylko w przypadku, kiedy usuwany jest ostatni element znajdujący się w kolejce.
C/C++
#include <iostream>
#include <cstdlib>

using namespace std;

struct node
{
    int val;
    node * next;
   
};
//Deklaracja
void queue( node *&, node *&, int x );
void dequeue( node *& );
void show( node * );

int main()
{
    int wybor, x;
    node * H = NULL;
    node * tail = new node;
    do
    {
        cout << "\nCo chcesz zrobic?\n1.Dodac elem\n2.Usunac elem\n3.SHOW\n4.Wyjscie" << endl;
        cin >> wybor;
        switch( wybor )
        {
        case 1:
            {
                cout << "Podaj element: ";
                cin >> x;
                queue( H, tail, x );
                break;
            }
        case 2:
            {
                dequeue( H );
                break;
            }
        case 3:
            {
                show( H );
                break;
            }
            default:
            {
                break;
            }
        }
    } while( wybor != 4 );
   
    system( "PAUSE" );
    return 0;
}

//Definicja
void queue( node *& H, node *& tail, int x )
{
    if( H == NULL )
    {
        tail->val = x; //przypisuje wartosci ogonowi i ustawiam go na heada, bo jest pierwszym elementem
        tail->next = NULL;
        H = tail;
    }
    else
    {
        node * tmp = new node;
        tmp->val = x;
        tmp->next = NULL;
        tail->next = tmp; // zmienna pomocnicza przypisuje do tail nexta i przesuwam wskaznik
        tail = tail->next;
    }
}
void dequeue( node *& H )
{
    if( H != 0 )
    {
        cout << "Sciagany element: " << H->val << endl;
        node * tmp = H;
        H = H->next;
        delete tmp;
    }
    else
    {
        cout << "Nie mozna sciagnac elementu" << endl;
        H = NULL;
    }
}
void show( node * pom )
{
    while( pom )
    {
        cout << pom->val << " ";
        pom = pom->next;
    }
}
P-159499
darko202
» 2017-03-28 14:28:22
problemem jest w funkcji
C/C++
void dequeue( node *& H )
{
    if( H != 0 )
    {
        cout << "Sciagany element: " << H->val << endl;
        node * tmp = H;
        H = H->next;
        delete tmp;
    }
    else
    {
        cout << "Nie mozna sciagnac elementu" << endl;
        H = NULL;
    }
}

myślę, że w linii  "H = H->next;

w sytuacji gdy masz już tylko 1 element 
zastanów się na co wskazuje H->next;

nie jest to tym co wcześniej deklarowaliśmy
node* H = NULL;

a niewątpliwie zmienna musi mieć adres
i to musisz poprawić

2.
Zapoznaj się z techniką debugowania kodu :)
P-159513
witeks44
Temat założony przez niniejszego użytkownika
» 2017-03-28 20:48:48
Dzięki, struktury wskaźniki to jeszcze trochę ciężki orzech dla mnie, muszę lepiej powtórzyć. Ogólnie chce właśnie zrobić tę listę bez użycia zmiennej przechowującej ilość elementów, która wszystko by w sumie uprościła :D . Choć nie rozumiem też kilku rzeczy zachodzących w moim kodzie(mimo, że sam go napisałem xd).
Chodzi mi o fragment
C/C++
void queue( node *& H, node *& tail, int x )
{
    if( H == NULL )
    {
        tail->val = x; //przypisuje wartosci ogonowi i ustawiam go na heada, bo jest pierwszym elementem
        tail->next = NULL;
        H = tail;
    }
    else
    {
        node * tmp = new node;
        tmp->val = x;
        tmp->next = NULL;
        tail->next = tmp; // zmienna pomocnicza przypisuje do tail nexta i przesuwam wskaznik
        tail = tail->next;
    }
}
chodzi mi o linię H=tail . Czy w tym przypadku przez to, że podane są przez referencję nie powinien H cały czas w  tym przypadku wskazywać na tail, w sensie zmieniając tail, nie powinien również H w przypadku późniejszych dodawanych elementów się zmieniać? Wiadomo tego nie chcę, ale nie rozumiem czemu właśnie tak nie działa :D
P-159548
darko202
» 2017-03-29 08:18:18
C/C++
//zastanówmy się czym jest
node *& tail

node * //wskaźnik
& //referencja - co oznacza że pokazuje zmienną zewnętrzną dla funkcji

//a czym jest H

node * H ////wskaźnik

// czym jest więc operacja na wskaźnikach ?
H = tail;

// wiedząc że wskaźnik przechowuje adres

//np. trzy wskaźniki
int x1, x2, x3;

int * wsk1 = & x1;( 0x3814f0 )
int * wsk2 = & x2;( 0x3814f4 )
int * wsk3 = & x3;( 0x3814f8 )

wsk2 = wsk3;
wsk1 = wsk1;
// na co teraz wskazuje wsk1
P-159559
witeks44
Temat założony przez niniejszego użytkownika
:D
» 2017-03-29 09:39:35
Noo skoro wsk1 przechowywało adres x1, no to wsk1=wsk1(adres zmiennej x1), czyli w sumie dalej wskazuje na adres wsk1 imo :D Czyli chodzi o to w moim przypadku, że H wskazuje na adres tail, ale potem tail wskazuje na nowy obszar pamięci? Dobrze to kminie?

P.S dzięki za pomoc z dequeue, wystarczyło dodać jednego ifa :D
P-159561
mateczek
» 2017-03-29 11:31:56
możesz sobie opakować tą kolejkę w klasy. I tak na szybko jakby to mogło wyglądać
C/C++
#include <iostream>

using namespace std;

struct node
{
    int val;
    node * next;
    node() {
        next = nullptr;
    }
   
};
class lista {
    node * baza;
    node * szczyt;
    int rozmiar;
public:
    lista() {
        baza = szczyt = nullptr;
        rozmiar = 0;
    }
    void queue( int val ) {
        if( rozmiar == 0 ) {
            baza = new node;
            baza->val = val;
            szczyt = baza;
        } else {
            node * temp = new node;
            temp->val = val;
            szczyt->next = temp;
            szczyt = temp;
        }
        rozmiar++;
    }
    int dequeue() {
        int return_val = 0;
        if( rozmiar >= 1 ) {
            rozmiar--;
            node * temp = baza;
            baza = baza->next;
            return_val = temp->val;
            delete temp;
        }
        return return_val;
    }
    void show() {
        node * el = baza;
        for( int i = 0; i < rozmiar; i++ ) {
            cout << el->val << endl;
            el = el->next;
        }
    }
};


int main()
{
    int wybor, x;
    lista mlista;
    do
    {
        cout << "\nCo chcesz zrobic?\n1.Dodac elem\n2.Usunac elem\n3.SHOW\n4.Wyjscie" << endl;
        cin >> wybor;
        switch( wybor )
        {
        case 1:
            {
                cout << "Podaj element: ";
                cin >> x;
                mlista.queue( x );
                break;
            }
        case 2:
            {
                cout << mlista.dequeue();
                break;
            }
        case 3:
            {
                mlista.show();
                break;
            }
            default:
            {
                break;
            }
        }
    } while( wybor != 4 );
   
    system( "PAUSE" );
    return 0;
}
P-159565
witeks44
Temat założony przez niniejszego użytkownika
» 2017-03-29 20:22:23
Klas niestety jeszcze nie znam, muszę w najbliższym czasie ogarnąć, jednakże bardzo dziękuję za znalezienie błędu jak i przykład ze wskaźnikiem, bo jak widać mój błąd tkwił właśnie w podstawowej idei wskaźników :D no i koledze za ten kod z klasą, mam nadzieję, że po teorii będzie jaśniejszy :D
Temat w sumie do zamknięcia, dziękuję za pomoc :D
P-159584
« 1 »
  Strona 1 z 1