Kontekst: Próbuję objąć głowę wskaźnikami, widzieliśmy je kilka tygodni temu w szkole i podczas dzisiejszej praktyki wpadłem na głupiego? problem, może to być dla ciebie bardzo proste, ale mam niewielkie lub żadne doświadczenie w programowaniu.Usuwanie wskaźnika w C++
Zdarzyło mi się sporo pytań na temat usuwania wskaźników, ale wszystkie wydają się być związane z usuwaniem klasy, a nie "prostym" wskaźnikiem (lub jakimkolwiek innym właściwym określeniem), oto kod I Próbuję uruchomić:
#include <iostream>;
using namespace std;
int main() {
int myVar,
*myPointer;
myVar = 8;
myPointer = &myVar;
cout << "delete-ing pointers " << endl;
cout << "Memory address: " << myPointer << endl;
// Seems I can't *just* delete it, as it triggers an error
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
// pointer being freed was not allocated
// *** set a breakpoint in malloc_error_break to debug
// Abort trap: 6
// Using the new keyword befor deleting it works, but
// does it really frees up the space?
myPointer = new int;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer continues to store a memory address.
// Using NULL before deleting it, seems to work.
myPointer = NULL;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer returns 0.
}
Więc moje pytania to:
- Dlaczego nie pierwsza praca przypadek? Wydaje się być najprostszym sposobem użycia i usunięcia wskaźnika? Błąd mówi, że pamięć nie została przydzielona, ale "cout" zwrócił adres.
- W drugim przykładzie błąd nie jest wyzwalany, ale robi cout wartości myPointer nadal zwraca adres pamięci?
- Czy # 3 naprawdę działa? Wydaje się pracować dla mnie, wskaźnik nie zapisuje już adresu, czy jest to właściwy sposób na usunięcie wskaźnika?
Przepraszam za długie pytanie, chciałem uczynić to jak najbardziej zrozumiałym, również powtórzyć, mam niewielkie doświadczenie programistyczne, więc jeśli ktoś mógłby odpowiedzieć na to używając warunków laika, byłoby to bardzo cenne!
Powodem, dla którego pierwszy przykład nie występuje, jest błąd. Tylko "usuń" to, co "nowe". Nie jest również wymagane, aby wskaźnik ustawił się na wartość NULL po usunięciu go. Jeśli chcesz tam bezpieczeństwa, użyj inteligentnych wskaźników, które zwalniają pamięć i dają błędy, gdy próbujesz uzyskać do nich dostęp, gdy czegoś nie trzymają. – chris
Hmm, nie jestem pewien, jakie są inteligentne wskaźniki, ale przyjrzę się temu, dzięki! – leopic
W skrócie, robią to, co opisałem. Aby pomieścić coś nowego, nazywasz 'reset' i uwalnia on stare. Aby go uwolnić bez wymiany, nazywasz 'release'. Kiedy wykracza poza zakres, ulega zniszczeniu i może zwolnić pamięć w oparciu o jej typ. 'std :: unique_ptr' jest przeznaczone tylko dla jednego właściciela. 'std :: shared_ptr' uwalnia go, gdy ostatni właściciel przestaje być właścicielem zasobu. Są również wyjątkowo bezpieczne. Jeśli przydzielisz zasób z jednym, a następnie napotkasz wyjątek, zasób zostanie odpowiednio zwolniony. – chris