39040

39040



166


ROZDZIAŁ 23. POWSZECHNE PRAKTYKI

void free_string(struct string *s)

{

assert (a !■ NULL);

free(s->data);    /* zwalniamy pamięć zajmowaną przez strukturę */

free(s);    /* usuwamy samą strukturę •/

>

Często łączy się destruktory z zerowaniem zwolnionych wskaźników.

Czasami dobrze jest ukryć definicję obiektu, żeby mieć pewność, że użyt kownicy nie utwo* rzą go ręcznie. Aby to zapewnić struktura jest definiowana w pliku źródłowym (lub prywatnym nagłówku niedostępnym dla użytkowników) zamiast w pliku nagłówkowym, a deklaracja wyprze<lzająca jest umieszczona w pliku nagłówkowym:

struct string;

struct string •create_string(const char »initial); void free_8tring(struct string *s);

Zerowanie zwolnionych wskaźników

Jak powiedziano już wcześniej, po wywołaniu freeO dla wskaźnika, staje się on “wiszącym wskaźnikiem”. Co gorsze, większość nowoczesnych platform nie potrafi wykryć, kiedy taki wskaźnik jest używany zanim zostanie ponownie przypisany.

Jednym z prostych rozwiązań tego problemu jest zapewnienie, że kitżdy wskaźnik jest zerowany mitychmiast po zwolnieniu:

free(p); p = NULL;

Inaczej niż w przypadku “wiszących wskaźników". na wielu nowoczesnych architekturach przy próbie użycia wyzerowanego wskaźnika pojawi się sprzętowy wyjątek. Dodatkowx». programy mogą zawierać sprawdzanie błędów dla zerowych wartości, ale nie dla “wiszących wskaźników”. Aby zapewnić, że jest to wykonywane dla każdego wskaźnika, możemy użyć makra:

•define FREE(p) do { free(p); (p) - NULL; } while(O)

(aby zobaczyć, dlaczego makro jest napisane w ten sposób, zoljacz Konwencje pisania makr)

Przy wykorzystaniu tej techniki destruktory powinny zerować wskaźnik, który przekazuje się ck) nich. więc argument musi być do nich przekazywany przez referencję. Na przykład, oto zaktualizowany destruktor z sekcji Konstruktor}- i destruktory:

void free_string(struct string **s)

{

assert(s !■ NULL &&    *8 !• NULL);

FREE((*s)->data);    /* zwalniamy pamięć zajmowaną przez strukturę •/

FREE(*s);    /* usuwamy strukturę */

)

Niestety, ten idiom nie jest wstanie pomóc w wypadku wskazywania przez inne wskaźniki zwolnionej pamięci. Z tego powodu niektórzy eksperci C uważają go za niebezpieczny, jako kreujący fałszywe |>oczucie bezpieczeństwa.



Wyszukiwarka

Podobne podstrony:
168ROZDZIAŁ 23. POWSZECHNE PRAKTYKI • logiczne “nie” Oprócz tego są także przesunięcia (« om/.
15381 IMG 23 (6) oznaczają w praktyce, przypomnijmy. te każda wypowiedź uc/ycida na lekcji wywołuje
PRAKTYCZNA UŻYTECZNOŚĆ BADAŃ PRASOZNAWCZYCH 23 O zapotrzebowaniu praktyków prasowych na informacje z
Najprostsza aplikacja public class Hello{ public static void main(String[ ]
inner33 (2) return fname.endsWith(ext); < void listJavaFiles(String dirName) { File dir = new Fil
DSC00311 (17) Reometria Reometria: Przegląd metod reometrycznych stosowanych powszechnie w praktyce,
public class Foiirth { public static void main(String[] args) { Tekst napis = new Tekst(){ void
DSCF2198 76 Mechanizacja Produkcji Zwierzęcej zielonek, powszechnie praktykowane, jest procesem dług
class ZADANIA{ public static void main(String[] args){ Zadanie z = new Zadanie();
Planowanie to powszechnie praktykowany rodzaj działalności człowieka, który umożliwia mu pewien stop
// Program04.java public class Program04 { public static void main(String[]{ // zamiana dwóch zmienn
co to jest zmienna? // Program03.java public class Program03 { public static void main(String[] args
co to jest zmienna? // Program03.java public class Program03 { public static void main(String[] args

więcej podobnych podstron