Wskaźniki - dlaczego nie można użyć 'delete' bez 'new' ?

0

Dlaczego takie użycie jest niewłaściwe ?

 
#include<iostream>
using namespace std;
int main()
{
        int someVariable=45;
        int *ptr=&someVariable;
        delete ptr;
        ptr=0;
        return 0;
}

Jeśli nie możemy użyć delete, to *ptr będzie w pamięci do zakończenia programu. Czy jeśli zrobimy takie coś, jak niżej, to będzie memory leak ?

#include<iostream>
using namespace std;
int main()
{
        int someVariable=45;
        int *ptr=&someVariable;
        ptr=0;
        return 0;
}
0

Nie będzie.

delete służy do zwalniania pamięci przydzielonej za pomocą new. W Twoim kodzie nie ma żadnego (dynamicznego) przydziału pamięci, wyciek pamięci nie jest możliwy.

0
Pan Pointer napisał(a):

Dlaczego takie użycie jest niewłaściwe ?

Bo stos to nie sterta.
http://pl.wikipedia.org/wiki/Stos_(informatyka)
Na stosie masz ramkę stosu, argumenty funkcji, również jej wewnętrzne zmienne i nie możesz ich zwolnić. Zrobi to kompilator generując odpowiedni kod maszynowy przy wyjściu z procedury.

Operatory New i Delete operują na Stercie: http://pl.wikipedia.org/wiki/Sterta_(informatyka)

Jeśli nie możemy użyć delete, to *ptr będzie w pamięci do zakończenia programu. Czy jeśli zrobimy takie coś, jak niżej, to będzie memory leak ?

Ptr będzie istniał tylko do wyjścia z procedury (no chyba że kompilator np. zdecyduje żeby w ogóle nie umieszczać go na stosie tylko np. w rejestrze). Nie będzie wycieku pamięci, wycieki dotyczą Sterty. Za Stos odpowiada kompilator.

0

Rozumiem. Czyli nie można użyć operatora delete bez wcześniejszej alokacji pamięci przez new. Dodatkowo każde użycie new determinuje późniejsze delete. Zgadza się ?

W poniższym kodzie nie ma memory leak'a.

 
#include<iostream>
using namespace std;
int main()
{
        int someVariable=45;
        int *ptr=&someVariable;
        ptr=0;
        return 0;
}

Jeśli natomiast nie ustawiłbym wskaźnika *ptr na NULL, a następnie wykorzystałbym ponownie ten wskaźnik, to... nadal nie byłoby memory leak'a ? Czy wycieki pamięci są związane tylko z wykorzystaniem operatora new ?

0

zależy jak byś użył tego wskaźnika ponownie.

#include <iostream>
using namespace std;
int main() {
        int someVariable=45;
        int *ptr=&someVariable;
        ptr=0;
        int foo=2;
        ptr = &foo;
        return 0;
}

jest poprawne

#include <iostream>
using namespace std;
int main() {
        int someVariable=45;
        int *ptr=&someVariable;
        ptr=0;
        ptr =new int(2)
        return 0;
}

spowoduje wyciek pamięci i musisz użyć delete

0

Czyli nie jest możliwy wyciek, gdy nie używamy operatora new ?

0

wyciek jest możliwy tam gdzie pamięć jest dynamicznie przydzielana. to że nie używasz operatora new (albo funkcji malloc, calloc, realloc) to nie znaczy, że wycieku nie będzie. być może jakaś biblioteka dynamicznie przydziela pamięć i programista ją musi zwolnić. przykład: jeśli otwierasz jakiś plik (funkcja fopen), musisz go zamknąć. ale wtedy nie używasz delete tylko funkcji do tego przeznaczonej fclose. delete używasz tylko z new, free z _alloc.

0

Ta biblioteka musi używać dynamicznego przydzielania pamięci. Ale my nie musimy tego wiedzieć. Dzięki. Będę musiał zajrzeć do serii @Gynvael Coldwind'a o pointera, to poszerzę wiedzę.

0

Jak chcesz się pobawić w usuwanie, to wydaje mi się, że wystarczy zabieg zamknięcia w klamerki bloku kodu korzystającego ze wskaźnika. Zmienna utworzona w {}, żyje do }.

#include<iostream>
using namespace std;
int main()
{
        int someVariable=45;
        {
                int *ptr=&someVariable;
        }//delete ptr;
        //ptr=0; // nie trzeba
        return 0;
}

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