Operator delete - kasowanie tablicy

0

Zaczynam z c++ nie wiem czy dobrze zrozumiałem ale mając kod :

int *tab = new int[20];

//wypełnianie tablicy:
for(int i = 0; i < 20; i++)
		tab[i] = i;

// pokazanie tresci - sposób niepoprawny przynajmniej dla kompilatora. Czemu ?
for(int i = 0; i < 20; i++) // wywala błąd ale pokazuje liczby od 0 do 19
	        cout << *tab++; 

// sposób poprawny :
int *wsk = tab; // ustawienie wskaznika na tab[0]
for(int i = 0; i < 20; i++)
		cout << *wsk++; // nie wywala błędu i pokazuje liczby od 0 do 19 ;D

// kasowanie tab
delete [] tab;

Dlaczego sposób z *tab++ jest niepoprawny ?

sorry za double post ale zapomniałem dopisać w tamtym pytania a przycisnąłem "wyślij"

W niepoprawnym przykładzie wypisuje mi wszystkie liczby przy czym wywala error. To przez delete [] tab iż wskaźnik nie jest ustawiony na początek tablicy ? ;O

0

Dlaczego sposób z *tab++ jest niepoprawny ?

Możę wstaw to w nawias: *(tab++)

int *wsk = tab; // ustawienie wskaznika na tab[0]

Nie prawda! tab teraz pokazuje na 19 element tablicy, a nie na pierwszy

A i może lepszym rozwiązaniem będzie po prostu: cout << *(tab + i); , a nie zmiana pozycji wskaźnika.

0

robiąc tmp++ gubisz oryginalny adres, który został zwrócony przez new. A do delete to właśnie ten oryginalny powinien zostać przekazany.

0

Dziwne że na 19 element bo jak wezmę

 
int *wsk = tab;
cout << *wsk;

to pokazuje mi 0 czyli to co jest w tab[0]

0

Bo nie wskazuje na 19 element tylko ZA 19 element, wychodzisz za tablicę, gdzie może leżeć absolutnie dowolna wartość z Twojego punktu widzenia.

0

Ten kawałek:

cout << *tab++;

w wyrażeniu *tab++ masz dwa operatory o różnych priorytetach. Gwiazdka * ma wyższy, więc wykona się jako pierwsza, a ++ ma niższy i wykona się po pierwszym - można to zapisać jako (*tab)++. *tab daje Ci dostęp do zmiennej int wskazywaną przez tab, a tab wskazuje na pierwszy element tablicy new int[20], czyli na element o indeksie [0]. Następnie (*tab)++ powoduje powiększenie pierwszego elementu o 1, więc pierwszy element tej tablicy będzie miał wartości od 0 do 19, drugi i pozostałe elementy nie zostaną zmienione.
Sposób rzekomo poprawny też robi dokładnie to samo. Inkrementuje pierwszy element nie dotykając pozostałych.

Aby uniknąć takich błędów zmienną wskaźnikową, która ma reprezentować całą tablicę trzeba deklarować tak:
int* const tab = new int[20];
Czyta się tę deklarację (jak wszystko w C/C++) idąc od identyfikatora zgodnie z priorytetami i wiązaniami operatorów/modyfikatorów: tab jest stałym (1) wskaźnikiem (2) na liczby typu int (3). Bo pierwszym modyfikatorem jest const, potem *, a następnie int.
Dzięki temu próba zrobienia ++tab lub tab++ spowoduje od razu błąd kompilacji, a sam tab będzie zawsze reprezentował początek tablicy.

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