2013-04-18 14 views
7

Natrafiłem na to przez sieć, podczas gdy studiowałem pewne rzeczy związane z wyciekiem pamięci.co to jest "odniesienie do zawieszenia" i "ogólny błąd ochrony"?

int* Function() 

{ 

    int arrays[10]; 

    /* Some code here */ 

    return &(arrays[0]); 

} 

Autor mówi, że powyższy fragment kodu jest poprawny, ale pamięć, która jest zwracana zostaną ponownie wykorzystane przez następną funkcję oddzwonienia, tak samo pamięci ma być używana w dwóch celach. Nazywa się to "odniesieniem do powieszenia" i może powodować straszliwe przerywane błędy lub staroświecki "ogólny błąd ochrony".

Byłoby wspaniale, jeśli ktoś może wyjaśnić, co „wisi odniesienie” & „Ogólny błąd ochrony”

+2

Autor nie bardzo dobrze zna C, lub źle ją reprezentujesz. Program ma niezdefiniowane zachowanie. –

+2

To nie dokładnie przecieka pamięć, ponieważ przydzielona tablica zostanie automatycznie zwolniona po powrocie funkcji. Jest to, co rozumie się przez wiszące odwołanie, zwracasz wskaźnik do pamięci przydzielonej na stosie.Gdy funkcja zwraca, tablica alokowana w stos jest deallokowana, dzięki czemu lokalizacja w pamięci może zostać nadpisana przez dane dla następnego wywołania funkcji, więc odwołanie do zwracanego wskaźnika da nieokreśloną wartość. –

+0

Yup wygląda jak Wiszący oznacza odwołanie się do czegoś na stosie, który już nie istnieje. Jakieś pojęcie o "ogólnym błędzie ochrony"? –

Odpowiedz

2

ja nie wiem, czy są to oficjalne wyjaśnienia, ale mam nadzieję, że to daje jakieś lepsze znaczenie dla tego przykładu:

Wiszące odniesienie: instrukcja return zwraca referencję (wskaźnik) do tablic. Jednak pamięć jest (lub może być) usunięta po zamknięciu funkcji, więc nie ma odniesienia do przydzielonej pamięci, która jest nazywana zwisającym odwołaniem.

Może to spowodować ogólny błąd ochrony. Ogólnie, pamięć, która nie jest przydzielona, ​​nie powinna być zapisywana. Jeśli spróbujesz to zrobić, ogólny błąd ochrony może zostać podniesiony przez system operacyjny.

1

arrays jest przydzielana na stosie, gdy wywoływana jest Function. Function zwraca adres struktury przydzielonej na stosie. Gdy Function zwraca wskaźnik stosu jest cofnięty, ale jego dane są nadal na stosie. Gdy poprzednio zwolniony region stosu zostanie użyty przez inną funkcję lub zakres, funkcja ta zapisze jego dane zakresu lokalnego w części stosu, która jest nadal potencjalnie dostępna z wcześniej zwróconego wskaźnika.

ten ma 2 konsekwencje:

  • W przypadku próby uzyskania dostępu do danych tablice z zewnątrz Function, dane te nie są wiarygodne i będzie (wkrótce lub mniej) uszkodzone przez nowego przydziału, który zastępowania obszar stosu .
  • Nowa funkcja przydzielona na stosie, jeśli nie inicjuje wszystkie pola To może zawierać jakieś brudne dane

Rezultatem jest niezdefiniowane zachowanie i może zależeć od kompilatora i skompilować opcji zbyt.

2

To nie dokładnie przecieka pamięć, ponieważ przydzielona tablica zostanie automatycznie zwolniona po powrocie funkcji. Jest to, co rozumie się przez wiszące odwołanie, zwracasz wskaźnik do pamięci przydzielonej na stosie. Gdy funkcja zwraca, tablica alokowana w stos jest deallokowana, dzięki czemu lokalizacja w pamięci może zostać nadpisana przez dane dla następnego wywołania funkcji, więc odwołanie do zwracanego wskaźnika da nieokreśloną wartość. Mogłoby to spowodować ogólny błąd ochrony, ponieważ wartość wskaźnika mogła zmienić się tak, że wskazywałaby poza prawidłową przestrzenią adresową, a wykrycie takiego wskaźnika spowodowałoby ogólny błąd ochrony.

Powiązane problemy