In meiner Firma gibt es eine Codierungsregel, die besagt, dass die Variable nach dem Freigeben von Speicher auf zurückgesetzt wird NULL
. Zum Beispiel ...
void some_func ()
{
int *nPtr;
nPtr = malloc (100);
free (nPtr);
nPtr = NULL;
return;
}
Ich habe das Gefühl, dass in Fällen wie dem oben gezeigten Code die Einstellung auf NULL
keine Bedeutung hat. Oder fehlt mir etwas?
Wenn es in solchen Fällen keine Bedeutung gibt, werde ich mich mit dem "Qualitätsteam" in Verbindung setzen, um diese Kodierungsregel zu entfernen. Bitte beraten.
c
coding-style
malloc
free
heap-memory
Alphaneo
quelle
quelle
ptr == NULL
bevor Sie etwas damit tun. Wenn Sie Ihre freien Zeiger nicht aufheben, erhalten Sie einenptr != NULL
immer noch unbrauchbaren Zeiger.Antworten:
Das Setzen nicht verwendeter Zeiger auf NULL ist ein defensiver Stil, der vor baumelnden Zeigerfehlern schützt. Wenn auf einen baumelnden Zeiger zugegriffen wird, nachdem er freigegeben wurde, können Sie zufälligen Speicher lesen oder überschreiben. Wenn auf einen Nullzeiger zugegriffen wird, kommt es auf den meisten Systemen sofort zu einem Absturz, der Sie sofort über den Fehler informiert.
Bei lokalen Variablen kann es etwas sinnlos sein, wenn "offensichtlich" ist, dass nach dem Freigeben nicht mehr auf den Zeiger zugegriffen wird. Daher ist dieser Stil besser für Mitgliedsdaten und globale Variablen geeignet. Selbst für lokale Variablen kann es ein guter Ansatz sein, wenn die Funktion nach der Freigabe des Speichers fortgesetzt wird.
Um den Stil zu vervollständigen, sollten Sie Zeiger auch auf NULL initialisieren, bevor ihnen ein echter Zeigerwert zugewiesen wird.
quelle
int *nPtr=NULL;
. Jetzt würde ich zustimmen, dass dies überflüssig wäre, wobei ein Malloc direkt in der nächsten Zeile folgt. Wenn sich jedoch zwischen der Deklaration und der ersten Initialisierung Code befindet, kann jemand die Variable verwenden, obwohl sie noch keinen Wert hat. Wenn Sie null initialisieren, erhalten Sie den Segfault. ohne könnten Sie wieder zufälligen Speicher lesen oder schreiben. Wenn die Variable später nur bedingt initialisiert wird, sollten spätere fehlerhafte Zugriffe sofort zu Abstürzen führen, wenn Sie daran gedacht haben, null zu initialisieren.Setzen eines Zeigers auf
NULL
nachherfree
ist eine zweifelhafte Praxis, die häufig als "gute Programmierregel" unter einer offensichtlich falschen Prämisse populär gemacht wird. Es ist eine dieser gefälschten Wahrheiten, die zur Kategorie "klingt richtig" gehören, aber in Wirklichkeit absolut nichts Nützliches erreichen (und manchmal zu negativen Konsequenzen führen).Angeblich soll das Setzen eines Zeigers auf
NULL
afterfree
das gefürchtete Problem "double free" verhindern, wenn derselbe Zeigerwert anfree
mehr als einmal übergeben wird. In der Realität tritt jedoch in 9 von 10 Fällen das eigentliche "Double Free" -Problem auf, wenn verschiedene Zeigerobjekte mit demselben Zeigerwert als Argumente für verwendet werdenfree
. Unnötig zu sagen, einen Zeiger aufNULL
danach setzenfree
in solchen Fällen absolut nichts bewirkt, um das Problem zu verhindern.Natürlich ist es möglich, auf ein "doppelt freies" Problem zu stoßen, wenn dasselbe Zeigerobjekt als Argument für verwendet wird
free
. In der Realität weisen solche Situationen jedoch normalerweise auf ein Problem mit der allgemeinen logischen Struktur des Codes hin, nicht nur auf ein zufälliges "doppelt frei". Ein geeigneter Weg, um das Problem in solchen Fällen zu lösen, besteht darin, die Struktur des Codes zu überprüfen und zu überdenken, um die Situation zu vermeiden, in der derselbe Zeigerfree
mehr als einmal übergeben wird. In solchen Fällen setzen Sie den Zeiger aufNULL
und das Betrachten des Problems als "behoben" nichts anderes als ein Versuch, das Problem unter den Teppich zu kehren. Im Allgemeinen funktioniert es einfach nicht, da das Problem mit der Codestruktur immer einen anderen Weg findet, sich zu manifestieren.Wenn Ihr Code speziell dafür ausgelegt ist, dass der Zeigerwert vorhanden ist
NULL
oder nichtNULL
, ist es vollkommen in Ordnung, den Zeigerwert aufNULL
after zu setzenfree
. Aber als allgemeine "Good Practice" -Regel (wie in "Setzen Sie immer Ihren Zeiger auf "NULL
Nachfree
") handelt es sich erneut um eine bekannte und ziemlich nutzlose Fälschung, die häufig von einigen aus rein religiösen, voodooähnlichen Gründen befolgt wird.quelle
foo* bar=getFoo(); /*more_code*/ free(bar); /*more_code*/ return bar != NULL;
. Hier Einstellungbar
zuNULL
nach dem Aufruffree
bewirkt , dass die Funktion denken , dass es nie eine Bar hatte und den falschen Wert zurück!Die meisten Antworten haben sich darauf konzentriert, ein Double Free zu verhindern, aber das Setzen des Zeigers auf NULL hat einen weiteren Vorteil. Sobald Sie einen Zeiger freigeben, kann dieser Speicher durch einen weiteren Aufruf von malloc neu zugewiesen werden. Wenn Sie immer noch den ursprünglichen Zeiger in der Nähe haben, kann es zu einem Fehler kommen, bei dem Sie versuchen, den Zeiger zu verwenden, nachdem Sie eine andere Variable freigegeben und beschädigt haben. Dann wechselt Ihr Programm in einen unbekannten Zustand und es können alle möglichen schlechten Dinge passieren (Absturz, wenn Sie Ich habe Glück, Datenkorruption, wenn Sie Pech haben. Wenn Sie den Zeiger nach dem Freiwerden auf NULL gesetzt hätten, würde jeder Versuch, diesen Zeiger später zu lesen / schreiben, zu einem Segfault führen, der im Allgemeinen einer zufälligen Speicherbeschädigung vorzuziehen ist.
Aus beiden Gründen kann es eine gute Idee sein, den Zeiger nach free () auf NULL zu setzen. Es ist jedoch nicht immer notwendig. Wenn beispielsweise die Zeigervariable unmittelbar nach free () den Gültigkeitsbereich verlässt, gibt es nicht viel Grund, sie auf NULL zu setzen.
quelle
free
, aber das macht tatsächlich Sinn.Dies wird als bewährte Methode angesehen, um ein Überschreiben des Speichers zu vermeiden. In der obigen Funktion ist dies nicht erforderlich, aber wenn dies erledigt ist, kann es häufig Anwendungsfehler finden.
Versuchen Sie stattdessen so etwas:
Mit DEBUG_VERSION können Sie Profilfreigaben im Debugging-Code erstellen, aber beide sind funktional gleich.
Bearbeiten : Hinzugefügt do ... während wie unten vorgeschlagen, danke.
quelle
do { } while(0)
Block, damitif(x) myfree(x); else dostuff();
es nicht kaputt geht.do {X} while (0)
IMO der beste Weg, um einen Makrokörper zu erstellen, der sich wie eine Funktion anfühlt und funktioniert. Die meisten Compiler optimieren die Schleife trotzdem.Wenn Sie den Zeiger erreichen, der frei war () d, kann er brechen oder nicht. Dieser Speicher wird möglicherweise einem anderen Teil Ihres Programms zugewiesen, und Sie erhalten eine Speicherbeschädigung.
Wenn Sie den Zeiger auf NULL setzen und dann darauf zugreifen, stürzt das Programm immer mit einem Segfault ab. Nicht mehr, manchmal funktioniert es, nicht mehr, stürzt auf unvorhersehbare Weise ab. Das Debuggen ist viel einfacher.
quelle
Das Setzen des Zeigers auf den
free
'd-Speicher bedeutet, dass jeder Versuch, über den Zeiger auf diesen Speicher zuzugreifen, sofort abstürzt, anstatt undefiniertes Verhalten zu verursachen. Es macht es viel einfacher festzustellen, wo etwas schief gelaufen ist.Ich kann Ihr Argument sehen: Da
nPtr
es unmittelbar danach aus dem RahmennPtr = NULL
geht, scheint es keinen Grund zu geben, es festzulegenNULL
. Im Fall einesstruct
Mitglieds oder an einem anderen Ort, an dem der Zeiger nicht sofort den Gültigkeitsbereich verlässt, ist dies jedoch sinnvoller. Es ist nicht sofort ersichtlich, ob dieser Zeiger von Code, der ihn nicht verwenden sollte, erneut verwendet wird oder nicht.Es ist wahrscheinlich, dass die Regel angegeben wird, ohne zwischen diesen beiden Fällen zu unterscheiden, da es viel schwieriger ist, die Regel automatisch durchzusetzen, geschweige denn, dass die Entwickler sie befolgen. Es tut nicht weh,
NULL
nach jedem Frei Zeiger zu setzen , aber es hat das Potenzial, auf große Probleme hinzuweisen.quelle
Der häufigste Fehler in c ist das Double Free. Grundsätzlich machst du so etwas
und es endet ziemlich schlecht, das Betriebssystem versucht, etwas bereits freigegebenen Speicher freizugeben und im Allgemeinen segfault es. Die bewährte Methode ist also, auf zu setzen
NULL
, damit Sie testen und prüfen können, ob Sie diesen Speicher wirklich freigeben müssenfree(NULL)
Beachten Sie auch, dass dies nichts bewirkt, sodass Sie die if-Anweisung nicht schreiben müssen. Ich bin nicht wirklich ein OS-Guru, aber ich bin ziemlich hübsch, selbst jetzt würden die meisten OSes doppelt doppelt abstürzen.Dies ist auch ein Hauptgrund, warum alle Sprachen mit Garbage Collection (Java, Dotnet) so stolz darauf waren, dieses Problem nicht zu haben und auch nicht die gesamte Speicherverwaltung den Entwicklern überlassen zu müssen.
quelle
p = (char *)malloc(.....); free(p); if(p!=null) //p!=null is true, p is not null although freed { free(p); //Note: checking doesnot prevent error here }
free(void *ptr)
kann den Wert des übergebenen Zeigers nicht ändern. Es kann den Inhalt des Zeigers, die an dieser Adresse gespeicherten Daten , aber nicht die Adresse selbst oder den Wert des Zeigers ändern . Das würde erfordernfree(void **ptr)
(was anscheinend vom Standard nicht erlaubt ist) oder ein Makro (was erlaubt und perfekt portabel ist, aber die Leute mögen keine Makros). Außerdem geht es bei C nicht um Bequemlichkeit, sondern darum, Programmierern so viel Kontrolle zu geben, wie sie wollen. Wenn sie nicht möchten, dass der zusätzliche Aufwand für das Setzen von Zeigern erhöht wirdNULL
, sollte er ihnen nicht aufgezwungen werden.free
" (zusammen mit Dingen wie "Umwandeln des Ergebnisses von Speicherzuweisungsfunktionen" oder "gedankenloses Verwenden von Typnamen mitsizeof
").Die Idee dahinter ist, die versehentliche Wiederverwendung des freigegebenen Zeigers zu stoppen.
quelle
Dies kann tatsächlich wichtig sein. Obwohl Sie den Speicher freigeben, könnte ein späterer Teil des Programms etwas Neues zuweisen, das zufällig im Raum landet. Ihr alter Zeiger würde jetzt auf einen gültigen Speicherblock verweisen. Es ist dann möglich, dass jemand den Zeiger verwendet, was zu einem ungültigen Programmstatus führt.
Wenn Sie den Zeiger auf NULL setzen, wird jeder Versuch, ihn zu verwenden, 0x0 dereferenzieren und genau dort abstürzen, was leicht zu debuggen ist. Zufällige Zeiger, die auf zufälligen Speicher verweisen, sind schwer zu debuggen. Es ist offensichtlich nicht notwendig, aber deshalb steht es in einem Best-Practice-Dokument.
quelle
Aus dem ANSI C-Standard:
"das undefinierte Verhalten" ist fast immer ein Programmabsturz. Um dies zu vermeiden, ist es sicher, den Zeiger auf NULL zurückzusetzen. free () selbst kann dies nicht tun, da nur ein Zeiger übergeben wird, kein Zeiger auf einen Zeiger. Sie können auch eine sicherere Version von free () schreiben, die den Zeiger NULL macht:
quelle
NULL
, um Maskierungsfehler zu vermeiden. stackoverflow.com/questions/1025589/… In beiden Fällen scheinen einige Fehler ausgeblendet zu sein.Ich finde, dass dies wenig hilfreich ist, da es meiner Erfahrung nach fast immer so ist, wenn Leute auf eine freigegebene Speicherzuordnung zugreifen, weil sie irgendwo einen anderen Zeiger darauf haben. Und dann widerspricht es einem anderen persönlichen Codierungsstandard, nämlich "Vermeiden Sie nutzlose Unordnung". Deshalb mache ich das nicht, da ich denke, dass es selten hilft und den Code etwas weniger lesbar macht.
Allerdings - ich werde die Variable nicht auf null setzen, wenn der Zeiger nicht erneut verwendet werden soll, aber oft gibt mir das übergeordnete Design einen Grund, sie trotzdem auf null zu setzen. Wenn der Zeiger beispielsweise Mitglied einer Klasse ist und ich gelöscht habe, worauf er verweist, lautet der "Vertrag" der Klasse, wenn Sie möchten, dass dieses Mitglied jederzeit auf etwas Gültiges verweist, sodass es auf null gesetzt werden muss aus diesem Grund. Eine kleine Unterscheidung, aber ich denke eine wichtige.
In c ++ ist es wichtig, immer darüber nachzudenken, wem es gehört diese Daten , wenn Sie einige Speicher zuweisen (es sei denn , Sie intelligente Zeiger verwenden , aber selbst dann ist einige Gedanken erforderlich). Und dieser Prozess führt dazu, dass Zeiger im Allgemeinen Mitglied einer Klasse sind und Sie möchten, dass sich eine Klasse jederzeit in einem gültigen Zustand befindet. Der einfachste Weg, dies zu tun, besteht darin, die Elementvariable auf NULL zu setzen, um anzuzeigen, dass sie zeigt zu nichts jetzt.
Ein allgemeines Muster besteht darin, alle Elementzeiger im Konstruktor auf NULL zu setzen und den Destruktoraufruf für alle Zeiger auf Daten löschen zu lassen, von denen Ihr Entwurf sagt, dass sie der Klasse gehören . In diesem Fall müssen Sie den Zeiger natürlich auf NULL setzen, wenn Sie etwas löschen, um anzuzeigen, dass Sie zuvor keine Daten besitzen.
Zusammenfassend lässt sich sagen, dass ich den Zeiger nach dem Löschen häufig auf NULL setze, aber dies ist Teil eines größeren Entwurfs und der Überlegungen, wem die Daten gehören, anstatt blind einer Codierungsstandardregel zu folgen. Ich würde dies in Ihrem Beispiel nicht tun, da ich denke, dass dies keinen Vorteil hat und es "Unordnung" hinzufügt, die meiner Erfahrung nach genauso für Fehler und schlechten Code verantwortlich ist wie diese Art von Dingen.
quelle
Kürzlich bin ich auf dieselbe Frage gestoßen, nachdem ich nach der Antwort gesucht habe. Ich bin zu diesem Schluss gekommen:
Es ist eine bewährte Methode, und Sie müssen diese befolgen, um sie auf allen (eingebetteten) Systemen portierbar zu machen.
free()
ist eine Bibliotheksfunktion, die sich ändert, wenn die Plattform geändert wird. Sie sollten also nicht erwarten, dass dieser Zeiger nach dem Übergeben des Zeigers auf diese Funktion und nach dem Freigeben des Speichers auf NULL gesetzt wird. Dies ist möglicherweise bei einigen für die Plattform implementierten Bibliotheken nicht der Fall.also immer gehen für
quelle
Diese Regel ist nützlich, wenn Sie versuchen, die folgenden Szenarien zu vermeiden:
1) Sie haben eine sehr lange Funktion mit komplizierter Logik und Speicherverwaltung und möchten den Zeiger nicht versehentlich später in der Funktion wieder auf gelöschten Speicher verwenden.
2) Der Zeiger ist eine Mitgliedsvariable einer Klasse mit einem recht komplexen Verhalten, und Sie möchten den Zeiger nicht versehentlich für gelöschten Speicher in anderen Funktionen wiederverwenden.
In Ihrem Szenario macht es nicht viel Sinn, aber wenn die Funktion länger wird, könnte es wichtig sein.
Sie können argumentieren, dass das Setzen auf NULL später tatsächlich Logikfehler maskieren kann, oder wenn Sie davon ausgehen, dass es gültig ist, stürzen Sie immer noch auf NULL ab, sodass dies keine Rolle spielt.
Im Allgemeinen würde ich Ihnen raten, es auf NULL zu setzen, wenn Sie denken, dass es eine gute Idee ist, und sich nicht darum zu kümmern, wenn Sie denken, dass es sich nicht lohnt. Konzentrieren Sie sich stattdessen darauf, kurze Funktionen und gut gestaltete Klassen zu schreiben.
quelle
Eine gute Methode zur Verwendung von Zeigern besteht darin, immer zu überprüfen, ob es sich um einen gültigen Zeiger handelt oder nicht. Etwas wie:
Das explizite Markieren des Zeigers als NULL nach dem Freigeben ermöglicht diese Art der Verwendung in C / C ++.
quelle
Dies könnte eher ein Argument sein, um alle Zeiger auf NULL zu initialisieren, aber so etwas kann ein sehr hinterhältiger Fehler sein:
p
landet an derselben Stelle auf dem Stapel wie der ersterenPtr
, sodass er möglicherweise noch einen scheinbar gültigen Zeiger enthält. Das Zuweisen zu*p
kann alle Arten von nicht verwandten Dingen überschreiben und zu hässlichen Fehlern führen. Insbesondere, wenn der Compiler lokale Variablen im Debug-Modus mit Null initialisiert, dies jedoch nicht tut, sobald die Optimierungen aktiviert sind. Die Debug-Builds zeigen also keine Anzeichen des Fehlers, während die Release-Builds zufällig explodieren ...quelle
Das Setzen des Zeigers, der gerade freigegeben wurde, auf NULL ist nicht obligatorisch, aber eine gute Vorgehensweise. Auf diese Weise können Sie vermeiden, 1) einen freigegebenen spitzen 2) zu verwenden
quelle
Einstellungen Ein Zeiger auf NULL dient zum Schutz vor so genannten Double-Free - eine Situation, in der free () für dieselbe Adresse mehrmals aufgerufen wird, ohne den Block an dieser Adresse neu zuzuweisen.
Double-Free führt zu undefiniertem Verhalten - normalerweise Heap-Beschädigung oder sofortiger Absturz des Programms. Das Aufrufen von free () für einen NULL-Zeiger führt zu nichts und ist daher garantiert sicher.
Die beste Vorgehensweise, es sei denn, Sie sind sich jetzt sicher, dass der Zeiger den Gültigkeitsbereich sofort oder sehr bald nach free () verlässt, besteht darin, diesen Zeiger auf NULL zu setzen. Selbst wenn free () erneut aufgerufen wird, wird er jetzt für einen NULL-Zeiger und ein undefiniertes Verhalten aufgerufen wird umgangen.
quelle
Die Idee ist, dass Sie, wenn Sie versuchen, den nicht mehr gültigen Zeiger nach dem Freigeben zu dereferenzieren, eher hart (segfault) als still und geheimnisvoll versagen möchten.
Aber sei vorsichtig. Nicht alle Systeme verursachen einen Segfault, wenn Sie NULL dereferenzieren. Unter (zumindest einigen Versionen von) AIX ist * (int *) 0 == 0 und Solaris optional mit dieser AIX- "Funktion" kompatibel.
quelle
Zur ursprünglichen Frage: Das Setzen des Zeigers auf NULL direkt nach dem Freigeben des Inhalts ist reine Zeitverschwendung, vorausgesetzt, der Code erfüllt alle Anforderungen, ist vollständig debuggt und wird nie wieder geändert. Auf der anderen Seite kann es sehr nützlich sein, einen freigegebenen Zeiger defensiv NULL zu machen, wenn jemand gedankenlos einen neuen Codeblock unter free () hinzufügt, wenn das Design des Originalmoduls nicht korrekt ist und wenn dies der Fall ist -kompiliert-aber-tut-nicht-was-ich-will Fehler.
In jedem System gibt es ein unerreichbares Ziel, es am einfachsten zu machen, das Richtige zu finden, und die irreduziblen Kosten für ungenaue Messungen. In C werden uns eine Reihe sehr scharfer, sehr starker Werkzeuge angeboten, die in den Händen eines Facharbeiters viele Dinge erzeugen und bei unsachgemäßer Handhabung alle möglichen metaphorischen Verletzungen verursachen können. Einige sind schwer zu verstehen oder richtig zu verwenden. Und Menschen, die von Natur aus risikoscheu sind, tun irrationale Dinge wie das Überprüfen eines Zeigers auf den NULL-Wert, bevor sie damit frei anrufen ...
Das Messproblem besteht darin, dass je komplexer der Fall ist, desto wahrscheinlicher ist es, dass Sie eine mehrdeutige Messung erhalten, wenn Sie versuchen, Gut von weniger Gut zu trennen. Wenn das Ziel darin besteht, nur gute Praktiken beizubehalten, werden einige mehrdeutige mit den eigentlich nicht guten verworfen. WENN Ihr Ziel darin besteht, das Nicht-Gute zu beseitigen, können die Unklarheiten beim Guten bleiben. Die beiden Ziele, nur gut zu bleiben oder eindeutig schlecht zu eliminieren, scheinen diametral entgegengesetzt zu sein, aber es gibt normalerweise eine dritte Gruppe, die weder die eine noch die andere ist, einige von beiden.
Bevor Sie sich an die Qualitätsabteilung wenden, durchsuchen Sie die Fehlerdatenbank, um festzustellen, wie oft, wenn überhaupt, ungültige Zeigerwerte Probleme verursachten, die notiert werden mussten. Wenn Sie einen echten Unterschied machen möchten, identifizieren Sie das häufigste Problem in Ihrem Produktionscode und schlagen Sie drei Möglichkeiten vor, um dies zu verhindern
quelle
Es gibt zwei Gründe:
Vermeiden Sie Abstürze beim Double-Freeing
Geschrieben von RageZ in einer doppelten Frage .
Vermeiden Sie die Verwendung bereits freigegebener Zeiger
Geschrieben von Martin v. Löwis in einer anderen Antwort .
quelle
Da Sie ein Qualitätssicherungsteam haben, möchte ich noch einen kleinen Punkt zur Qualitätssicherung hinzufügen. Einige automatisierte QS-Tools für C kennzeichnen Zuweisungen an freigegebene Zeiger als "nutzlose Zuweisung an
ptr
". Zum Beispiel sagt PC-Lint / FlexeLint von Gimpel Softwaretst.c 8 Warning 438: Last value assigned to variable 'nPtr' (defined at line 5) not used
Es gibt Möglichkeiten, Nachrichten selektiv zu unterdrücken, sodass Sie beide QS-Anforderungen erfüllen können, falls Ihr Team dies entscheidet.
quelle
Es ist immer ratsam, eine Zeigervariable mit NULL zu deklarieren, z.
Angenommen , ptr zeigt auf die Speicheradresse 0x1000 . Nach der Verwendung
free(ptr)
ist es immer ratsam, die Zeigervariable durch erneutes Deklarieren auf NULL zu annullieren . z.B:Wenn die Zeigervariable nicht erneut zu NULL deklariert wird, zeigt sie weiterhin auf dieselbe Adresse ( 0x1000 ). Diese Zeigervariable wird als baumelnder Zeiger bezeichnet . Wenn Sie eine andere Zeigervariable definieren (z. B. q ) und dem neuen Zeiger dynamisch eine Adresse zuweisen, besteht die Möglichkeit, dass dieselbe Adresse ( 0x1000 ) von einer neuen Zeigervariablen übernommen wird. Wenn Sie denselben Zeiger ( ptr ) verwenden und den Wert an der Adresse aktualisieren, auf die derselbe Zeiger ( ptr ) zeigt, schreibt das Programm am Ende einen Wert an die Stelle, auf die q zeigt (seit p und q sind auf dieselbe Adresse zeigen (0x1000) )).
z.B
quelle
Lange Rede, kurzer Sinn: Sie möchten nicht versehentlich (versehentlich) auf die Adresse zugreifen, die Sie freigegeben haben. Wenn Sie die Adresse freigeben, können Sie zulassen, dass diese Adresse im Heap einer anderen Anwendung zugewiesen wird.
Wenn Sie den Zeiger jedoch nicht auf NULL setzen und versehentlich versuchen, den Zeiger zu de-referenzieren, oder den Wert dieser Adresse ändern. SIE KÖNNEN ES NOCH TUN. ABER NICHT ETWAS, WAS SIE LOGISCH WOLLEN.
Warum kann ich immer noch auf den Speicherplatz zugreifen, den ich freigegeben habe? Denn: Möglicherweise haben Sie den Speicher freigegeben, aber die Zeigervariable enthielt noch Informationen zur Heapspeicheradresse. Als Verteidigungsstrategie setzen Sie sie bitte auf NULL.
quelle