Nie rozumiem różnicy między wiszącym wskaźnikiem a wyciekiem pamięci. Jak te dwa terminy są powiązane?
A wskaźnik zwisające punkty do pamięci, która została już zwolniona. Magazyn nie jest już przydzielony. Próba uzyskania do niego dostępu może spowodować błąd segmentacji.
Typowy sposób na zakończenie z wiszącym wskaźnikiem:
char *func()
{
char str[10];
strcpy(str, "Hello!");
return str;
}
//returned pointer points to str which has gone out of scope.
Zwracasz adres, który był zmienną lokalną, która wyszłaby poza zakres, gdyby kontrola czasu została zwrócona do funkcji wywołującej. (Niezdefiniowane zachowanie)
Innym typowym przykładem wiszącego wskaźnika jest dostęp do lokalizacji pamięci za pośrednictwem wskaźnika, po jawnym wywołaniu free w tej pamięci.
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!
Wyciek pamięci jest pamięć, która nie została zwolniona, nie ma sposobu, aby uzyskać dostęp (lub zwolnić go) teraz, ponieważ nie istnieją sposoby, aby dostać się do niego już. (Np. Wskaźnik, który był jedynym odniesieniem do lokalizacji pamięci przydzielanej dynamicznie (i nie zwalnianej), który wskazuje teraz gdzie indziej.)
void func(){
char *ch = malloc(10);
}
//ch not valid outside, no way to access malloc-ed memory
Char-ptr ch jest zmienną lokalną, która na końcu funkcji wychodzi poza zakres, powodując wyciek z dynamicznie przydzielonych 10 bajtów .
Możesz myśleć o nich jako o swoich przeciwieństwach.
Kiedy zwolnisz obszar pamięci, ale nadal utrzymujesz do niego wskaźnik, wskaźnik ten zwisa:
char *c = malloc(16); free(c); c[1] = 'a'; //invalid access through dangling pointer!
Gdy zgubisz wskaźnik, ale zachowasz przydzieloną pamięć, masz wyciek pamięci:
void myfunc() { char *c = malloc(16); } //after myfunc returns, the the memory pointed to by c is not freed: leak!
źródło
Zwisające wskaźnik jest taki, który ma wartość (NOT NULL), który odnosi się do jakiejś pamięci, która nie jest ważny dla tego typu obiektu można się spodziewać. Na przykład, jeśli ustawisz wskaźnik na obiekt, nadpisujesz tę pamięć czymś innym niepowiązanym lub zwolnisz pamięć, jeśli została przydzielona dynamicznie.
Wyciek pamięci jest, kiedy dynamicznie przydzielić pamięci ze sterty ale nigdy uwolnić go, być może dlatego, że stracił wszystkie odwołania do niego.
Są one powiązane w tym sensie, że są to sytuacje związane z niewłaściwie zarządzanymi wskaźnikami, zwłaszcza w przypadku dynamicznie przydzielanej pamięci. W jednej sytuacji (wiszący wskaźnik) prawdopodobnie zwolniłeś pamięć, ale później próbowałeś się do niej odwołać; w drugim (wyciek pamięci) zapomniałeś całkowicie zwolnić pamięć!
źródło
Wskaźnik wiszący
Jeśli jakikolwiek wskaźnik wskazuje adres pamięci dowolnej zmiennej, ale po usunięciu jakiejś zmiennej z tej lokalizacji pamięci, podczas gdy wskaźnik nadal wskazuje taką lokalizację w pamięci. Taki wskaźnik jest znany jako wskaźnik wiszący, a ten problem jest znany jako problem z wiszącym wskaźnikiem.
#include<stdio.h> int *call(); void main(){ int *ptr; ptr=call(); fflush(stdin); printf("%d",*ptr); } int * call(){ int x=25; ++x; return &x; }
Wynik: wartość śmieci
Objaśnienie: zmienna x jest zmienną lokalną. Jego zasięg i czas życia są zawarte w wywołaniu funkcji, stąd po zwróceniu adresu x zmienna x stała się martwa, a wskaźnik nadal wskazuje, ptr nadal wskazuje na tę lokalizację.
Rozwiązanie tego problemu: spraw, aby zmienna x była zmienną statyczną. Innymi słowy, możemy powiedzieć, że wskaźnik, którego obiekt wskazujący został usunięty, jest nazywany wskaźnikiem wiszącym.
Wyciek pamięci
W informatyce wyciek pamięci występuje, gdy program komputerowy nieprawidłowo zarządza alokacjami pamięci. Jak w prostym przypadku, przydzieliliśmy pamięć, a nie Wolny inny termin językowy mówi, że nie zwalniaj go, wyciek pamięci, jest to śmiertelne dla aplikacji i nieoczekiwana awaria.
źródło
Wskaźnik pomaga utworzyć zakres zdefiniowany przez użytkownika dla zmiennej, która jest nazywana zmienną dynamiczną. Zmienna dynamiczna może być pojedynczą zmienną lub grupą zmiennych tego samego typu (
array
) lub grupą zmiennych różnych typów (struct
). Domyślny zakres zmiennej lokalnej rozpoczyna się, gdy sterowanie wchodzi do funkcji i kończy się, gdy sterowanie wychodzi z tej funkcji. Domyślny globalny zakres zmienny zaczyna się w momencie wykonania programu i kończy się po zakończeniu programu.Ale zakres dynamicznej zmiennej, która jest trzymana przez wskaźnik, może rozpoczynać się i kończyć w dowolnym momencie wykonywania programu, o czym decyduje programista. Zawieszanie i wyciek pamięci pojawiają się tylko wtedy, gdy programista nie poradzi sobie z końcem zakresu.
Wyciek pamięci nastąpi, jeśli programista nie napisze kodu (
free
wskaźnika) dla końca zakresu dla zmiennych dynamicznych. W każdym razie, gdy program wyjdzie, cała pamięć procesu zostanie zwolniona, w tym czasie ta wyciekająca pamięć również zostanie zwolniona. Ale spowoduje to bardzo poważny problem dla procesu, który trwa długo.Gdy zakres zmiennej dynamicznej dobiegnie końca (zostanie zwolniony),
NULL
należy go przypisać do zmiennej wskaźnikowej. W przeciwnym razie, jeśli kod nieprawidłowo uzyska dostęp do niego, nastąpi niezdefiniowane zachowanie. Tak więc wiszący wskaźnik jest niczym innym jak wskaźnikiem wskazującym dynamiczną zmienną, której zakres jest już zakończony.źródło
Wyciek pamięci : gdy w stercie znajduje się obszar pamięci, ale w stosie nie ma zmiennej wskazującej na tę pamięć.
char *myarea=(char *)malloc(10); char *newarea=(char *)malloc(10); myarea=newarea;
Dangling pointer : Gdy zmienna wskaźnika w stosie, ale nie ma pamięci w stercie.
char *p =NULL;
Wiszący wskaźnik próbujący wyłuskać odwołanie bez przydzielania miejsca spowoduje błąd segmentacji.
źródło
Wskaźnik wskazujący na lokalizację pamięci, która została usunięta (lub zwolniona) jest nazywana wskaźnikiem wiszącym.
#include <stdlib.h> #include <stdio.h> void main() { int *ptr = (int *)malloc(sizeof(int)); // After below free call, ptr becomes a // dangling pointer free(ptr); }
po więcej informacji kliknij TUTAJ
źródło
—— z https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/
źródło