Cześć. Mam pytanie do zwalniania pamięci. Przy alokacji tablicy dynamicznej tworzymy wskaźnik int * tab=new int[10], przy usuwaniu wywołujemy delete[] tab. I tu moje pytanie: delete[] tab usuwa ta tablice a co sie dzieje ze wskaźnikiem? Również jest usuwany czy zostaje i trzeba go usunąć delete tab?
Pozdrawiam
Wesołych Świąt
Wskazuje na śmieci jeżeli nie ustawisz go na nullptr
co jest zalecanym rozwiązaniem po zwolnieniu pamięci.
Wesolych również :-)
delete tab;
- nie usuwa wskaźnika.
-
delete
należy wywołać tyle razy ile wywołanonew
- do
delete
należy przekazać to co zwrócił odpowiadający munew
- jeżeli
new
był z nawiasami kwadratowymi to delete również musi być z nawiasami kwadratowymi - to teoretycznie można zignorować i zawsze dawaćdelete
bez nawiasów kwadratowych ale takie przyzwyczajenie kiedyś się zemści, przy zwalnianiu pamięciFoo *foo=new Foo[10]; delete foo;
wywoła się tylko jeden destruktor zamiast 10-ciu.
to jak mam usuwać wskaźnik? Załóżmy ze mam funkcje która tworzy tymczasowy wskaźnik int tmp*=new int[k] po czym stosujemy delete[] tmp; i wywołujemy ją kilkaset razy. Czyli mamy wtedy kilkaset "luźnych wskaźników"?
Którego słowa nie rozumiesz w zdaniu: - "... należy wywołać tyle razy ile wywołano ..." - raz wywołałeś new
to równio raz wywołujesz delete
Samego wskaźnika jako obieku, który wskazuje na inny obiekt w pamięci nie da sie usunąć czy zwolnić. Zwalnia sie tylko pamięć po obiekcie, na który wskazywuje wskaźnik.
Wybacz ale dopiero się uczę. Kolega grzesiek51114 napisał ze wskaźnik bedzie wskazywał na śmieci. Jeszcze raz proszę o wytłumaczenie.
Jak raz wywołam int *tab=int new[10]; a później delete[] tab to usunę również wskaźnik? Czy bede mógł go jeszcze użyć?
Ok, dzięki za pomoc. Czyli nie muszę usuwać wskaźnika jako takiego, to nie będą wycieki pamięci?
Nie istnieje żadna możliwość usunięcia wskaźnika - bo to jest zmienna która ma wartość.
#include <iostream>
using namespace std;
int main() {
int *ptr = nullptr;
cout << "przed alokacja: " << ptr << endl;
ptr = new int[10];
cout << "po alokacji: " << ptr << endl;
delete[] ptr;
cout << "po zwolnieniu: " << ptr << endl;
ptr = nullptr;
cout << "po wyzerowaniu: " << ptr << endl;
return 0;
}
Przykładowy output:
przed alokacja: 0
po alokacji: 0x9579a10
po zwolnieniu: 0x9579a10
po wyzerowaniu: 0
Ręczne zarządzanie zasobami (np. wołanie new
i delete
) to antyidiom w C++. Użyj kontenerów (np. std::vector
) lub smart pointerów.