usuwanie wskaźnika problem

0

Witam

może mi ktoś wytłumaczyć na tym przykładzie dlaczego kompilator wywala błąd ochrony pamięci ? (kluczowy moment to funkcja B::void fun()) zdaje mi się ze ze wskaźnika już nie korzystam a więc usuwam i wychodzę z funkcji...Jak w takim razie poprawnie usunąć taki wskaźnik.

#include <iostream>

using namespace std;

class A
{
        int *tab;

        public :
        A()
        {
                tab = new int[10];
                for (int i = 0; i < 10; i++)
                        tab[i] = i;
        }

        ~A()
        {
                delete []tab;
        }
        int* return_tab()
        {
                return tab;
        }
};

class B
{
        A *obj_A;
        int x;
        public :
        B()
        {
                obj_A = new A;
        }

        ~B()
        {
                delete obj_A;
        }

        int return_x()
        {
                return x;
        }

        void fun()
        {
                int *tmp_wsk = obj_A->return_tab();

                for (int i = 0; i < 10; i++)
                {
                        if (tmp_wsk[i] > 5)
                        {
                                x = tmp_wsk[i];
                                delete tmp_wsk; // tutaj usuwanie i wyjscie z funkcji
                                return;
                        }
                }
        }
};

int main()
{
        B obj_B;

        obj_B.fun();
        cout << obj_B.return_x();

        return 0;
}
0

Bo w destruktorze klasy A usiłujesz usunąć drugi raz miejsce w pamięci, w którym są już jakieś śmieci. Dlatego dla bezpieczeństwa po instrukcji delete powinno się ustawiać wskaźnik, tak aby wskazywał na nic wsk = 0; wtedy nawet jak będziesz próbował drugi raz usunąć to na co wskazuje wskaźnik program nie wysypie się.

0

hmm no właśnie dodanie tmp_wsk; = NULL; albo tmp_wsk; = 0; nic nie daje...dalej błąd

A nie jest tak że nawet podczas przypisania tmp_wsk = obj_A->return_tab(); mamy dwa wskaźniki do tych samych danych i możemy je usuwać oddzielnie ?

czyli po delete tmp_wsk; wciąż *tab wskazuje na początek tablicy i to też kiedyś trzeba usunąć ?

A i tak usuniecie tmp_wsk wywala bład ;/ sprawdzałem na 2 kompilatorach...

0

Naos, możesz mieć i milion wskaźników, które pokazują ten sam adres w pamięci. W klasie B tworzysz nowy wskaźnik, który pokazuje na składnik klasy A.
Poza tym co robisz w tmp_wsk; = 0;? Powinno być tmp_wsk = 0; ;)

0

literówka :)

Niby rozumiem swój błąd, chociaż zawsze myślałem inaczej.

Wiec obejdzie się bez kasowania dla tmp_wsk i wystarczy ustawić go na 0 ?

a dane w pamięci skasują się w destruktorze wraz z delete []tab ?

0

Znaczy w klasie B nie musisz go ustawiać na 0 skoro go tam nie kasujesz :) I tak, wystarczy delete w klasie A.

0

zawsze miałem inne wyobrażenie o tym :) widocznie coś nie doczytałem...

A piszę troszkę "grubszy" program na zaliczenie i właśnie napotkałem taki problem i musiałem się upewnić :)

Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1