Najczęściej popełnione błędy

twonek

Baśń o wskaźniku

Wyobraź sobie, że Twój komputer ma tylko 4 komórki pamięci, każda zdolna pomieścić jeden int.
Komórki mają adresy 1, 2, 3, 4.

[  ?  ] [  ?  ] [  ?  ] [  ?  ]

Teraz jeśli masz:

int foo;

Zmienna foo zostaje utworzona w którejś komórce pamięci (decyzja należy do systemu operacyjnego), powiedzmy w komórce 3.
Wartość foo nie została inicjalizowana, więc jest nieznana i nie wolno do niej się odwołać. Czyli: foo ma adres 3 i niezainicjalizowaną wartość.

[  ?  ] [  ?  ] [foo = ?] [  ?  ]
foo = -14545;

Teraz foo ma wartość -14545, inaczej mówiąc w komórce 3 jest teraz liczba -14545.

[  ?  ] [  ?  ] [foo = -14545] [  ?  ]
int* ptr;

Zmienna ptr (wskaźnik to też tylko zmienna jak każda inna) zostaje utworzona powiedzmy w komórce 1. Ma niezainicjalizowaną wartość, czyli na nic nie wskazuje. W C++ przyjmuje się również, że jeśli wskaźnik ma wartość 0 (albo jako makro NULL) to oznacza że też na nic nie wskazuje, bo żadna zmienna nie ma takiego adresu.

[ptr = ?] [  ?  ] [foo = -14545] [  ?  ]
ptr = &foo;

ptr ma teraz wartość 3, czyli wskazuje na komórkę, w której jest zmienna foo (albo w skrócie wskazuje na foo). Czyli zmienna ptr ma adres 1 i wartość 3.

[ptr = 3] [  ?  ] [foo = -14545] [  ?  ]

koniec baśni




Wskaźnik to zmienna. Wszystkie podstawowe operacje typu odczyt, przypisanie zachowują się tak samo jak w przypadku zmiennych niewskaźnikowych.

int zmienna;
zmienna = <wartosc_typu_int>;
funkcja_oczekujaca_int(zmienna);
int* wskaznik;
wskaznik = <wartosc_typu_wskaznik_do_int>;
funkcja_oczekujaca_wskaznika_int(wskaznik);

Wskaźnik **nie** alokuje pamięci dla obiektu, na który ma wskazywać. ```cpp int* wskaznik; *wskaznik = 5; // hola hola, a skąd masz pamięć na przechowywanie liczby 5? ``` Pomijamy tutaj inny błąd związany z odczytem niezainicjalizowanej zmiennej.
Od alokacji pamięci jest `new`, którego używania należy unikać (korzystając zamiast tego ze zmiennych na stosie, inteligentnych wskaźników itd.)
int* wskaznik = new int;
*wskaznik = 5;        // był new, więc pamięć jest
delete wskaznik;    // zawsze pamiętaj o delete jeśli używasz new


Analogicznie w przypadku używania wskaźnika jako "tablicy"

int* tab;
tab[1] = 5;      // no halo, a pamięć to gdzie została zaalokowana?
int* tab = new int[50];
tab[1] = 5;       // alokowano pamięć, wszystko ok
delete[] tab;



[Ciągle w rozbudowie]

0 komentarzy