Przeskocz do treści

Delta mi!

Wiszące referencje. Czy można wyeliminować to zagrożenie?

Andrzej Salwicki

o artykule ...

  • Publikacja w Delcie: maj 2017
  • Publikacja elektroniczna: 1 maja 2017
  • Autor: Andrzej Salwicki
    Afiliacja: Dombrova Research
  • Wersja do druku [application/pdf]: (115 KB)

W tej pracy przedstawimy groźne zjawisko - błąd wiszących referencji - jakie występuje w programowaniu obiektowym, np. w C++, Pascalu, C. W kolejnym artykule omówimy rozwiązanie pozwalające wyeliminować ten błąd. Zacznijmy od krótkiej ekspozycji problemów, jakie napotykamy podczas zarządzania pamięcią obiektów w każdym języku programowania obiektowego.

obrazek

Obiekty są  ○ 1 tworzone,  ○ 2 współdzielone,  ○ |3 wykorzystywane i 4○ ewentualnie stają się niepotrzebne.

Będziemy tutaj abstrahować od wielu szczegółów, takich jak rozmiar obiektu, jego typ, sposoby zarządzania odzyskiwaną pamięcią, itp.

Obiekty tworzymy, wykonując polecenie x new(…), które tworzy nowy obiekt o i przypisuje go jako wartość zmiennej x. Np. |u new(Re 3.0,Im 4.5). nowyobiekto

Obiekt o utworzony przez polecenie new może stać się wartością kilku zmiennych. Np. w ten sposób: y x;...;z y . Ma wtedy miejsce współdzielenie (ang. aliasing, sharing) obiektu o przez zmienne x, y, z.

Współpracę z obiektem o, który jest wartością zmiennej x, można sprowadzić do trzech przypadków:

  • inspekcja - ma miejsce wtedy, gdy odczytujemy wartość zmiennej zapisanej w obiekcie, np. trzeba wyznaczyć wartość wyrażenia x.attr.
  • uaktualnienie - gdy przypisujemy nową wartość zmiennej w obiekcie x, np. x.at 17 .
  • serwis - gdy wykonujemy polecenie wykonania usługi zdefiniowanej w obiekcie, np. call |x.NarysujOkr g p,12 .

Wszystkie trzy przypadki powinny rozpoczynać się od sprawdzenia, czy wartością zmiennej x jest jakiś żywy obiekt, czy też specjalna wartość null.

Na koniec sytuacja, gdy program zaniecha współpracy z obiektem o i gdy przestaje on być wartością jakiejkolwiek zmiennej. Taki obiekt nazywany jest śmieciem. Mądry programista pozbędzie się śmieci, uwalniając pamięć zajętą przez te obiekty.

Jakie problemy stwarza zarządzanie pamięcią obiektów? Dwa główne zagrożenia dla obliczeń naszego programu to:

 wiszące referencje i | zaśmiecanie pamięci.

Najwięcej szkód wyrządza błąd wiszących referencji (ang. dangling reference error). Można go nazwać cichym zabójcą, ponieważ program, w którym usadowił się taki błąd, może wydawać się bezpieczny przez długie miesiące i lata, zanim użytkownicy zorientują się, że program działa nieprawidłowo. Koszty nieprawidłowego działania mogą okazać się bardzo wysokie. (Zdarzało się, że nieprawidłowe działanie programu powodowało nawet śmierć ludzi!) Koszty wykrycia błędu i zlokalizowanie miejsca w programie, w którym ten błąd wystąpił, też nie są bagatelne. Nie umiem podać rzetelnych statystyk. Na pewno jednak tylko finansowe straty w ostatnich trzydziestu latach to kwoty rzędu setek milionów euro. Czy można skonstruować taki program, który analizowałby programy i wykrywał miejsce wystąpienia błędu wiszących referencji w programie?

Niestety, taki algorytm nie istnieje. Wytłumaczenie jest proste: gdyby istniał taki algorytm A, to moglibyśmy skonstruować inny algorytm H, | który wykrywałby, czy dowolny dany tekst programu zakończy obliczenia w czasie skończonym, czy też obliczenie będzie przedłużane bez ograniczenia (czyli program zapętli się). Jednakże - jak wiadomo - ten problem jest nierozstrzygalny.

  • Cały artykuł dostępny jest w wersji do druku [application/pdf]: (115 KB)