2009-02-02 4 views
9

Ist die Wiederverwendung von Zeigern nach dem Freigeben der Daten, auf die sie verweisen, sicher und vorhersehbar?Ist es sicher, Zeigervariablen wiederzuverwenden, nachdem sie freigegeben haben, worauf sie zeigen?

Zum Beispiel:

char* fileNames[] = { "words.txt", "moreWords.txt" }; 
char** words = NULL; 
int* wordsCount = NULL; 
for (i = 0; i < 2; ++i) { 
    data = fopen(fileNames[i], "r"); 
    words = readWords(data); 
    wordsCount = countWords(words); 

    free(wordsCount); 
    for (j = 0; words[j]; ++j) 
     free(words[j]); 
    free(words); 
    fclose(data); 
} 

* Fehlerprüfung

weggelassen

ich den Code laufen lasse und es scheint zu laufen (keine Warnungen, Fehler oder Probleme mit dem Speicher), aber ich frage mich, ob dies sicher ist und vorhersehbar in den meisten Umgebungen (speziell in einer typischen Linux-Umgebung) zu verwenden?

Wenn dies nicht "sicher und vorhersehbar" ist, was ist der beste Weg, die gleichen Operationen an zwei verschiedenen Dateien durchzuführen, ohne die doppelte Anzahl an Zeigern usw. zu erstellen?

EDIT: ich frage, ob es um die Wiederverwendung eines Zeigers Variable nach Freigabe in Ordnung ist, was es deutete auf. Ich verstehe, dass Sie keinen Zeiger Wert nach dem Freigeben verwenden sollten. Angenommen, der Code funktioniert einwandfrei (es funktioniert wie vorgesehen, der Speicher wird ordnungsgemäß freigegeben und so). Ich kann die Spezifikation nicht ändern. für diese Aufgabe.

Danke!

+0

Ich sehe nirgends in Ihrem Code, wo Sie nichts wiederverwenden, nachdem Sie es freigegeben haben. –

+0

Sie sollten Ihre Wordcount-Funktion einen int zurückgeben, anstatt int * ... Platz für ein int in diesem Kontext vergeben ist sinnlos ... –

+0

Ich lese in zwei verschiedenen Dateien und die gleichen Operationen (readWords, countWords, etc) für jede Datei. Für mich bedeutet dies, dass ich die Zeiger "wiederverwenden" würde, aber sie würden auf verschiedene Stellen (möglicherweise) bei jeder Iteration der Schleife zeigen. –

Antwort

22

Was Sie tun, ist in Ordnung: Denn nachdem Sie einen Zeiger losgelassen haben, initialisieren Sie ihn neu, bevor Sie ihn wiederverwenden.

Wenn die Frage ist "ist es sicher, einen Zeiger Wert nach dem Freigeben zu verwenden" dann lautet die Antwort "nein". Wenn die Frage ist "ist es sicher, einen Zeiger Variable nach dem Freigeben seines Wertes zu verwenden" dann lautet die Antwort "ja, vorausgesetzt, Sie initialisieren es zu einem (neuen) gültigen Wert, bevor Sie es wiederverwenden".

+0

Okay. Vielen Dank. Ich nehme an, ich sollte meine Frage umschreiben, um zu sagen, eine Zeigervariable wiederzuverwenden. Ich weiß, dass du keinen Pointer-Wert verwenden solltest, nachdem er frei ist. –

3

Ja. Das ist sicher. (Hässlich, aber sicher :))

+0

Lesen Sie die Frage und sagen Sie mir, ob es sicher ist, "Zeiger nach dem Freigeben der Daten, auf die sie zeigen, wiederzuverwenden". –

+0

Plus, im Allgemeinen hässlich == nicht sicher –

+0

Ja, es ist sicher, die Zeiger auf verschiedene Speicherblöcke neu zuzuweisen. Es ist nicht sicher, den Zeiger zu verwenden, um auf den Speicherblock zuzugreifen, den Sie gerade freigegeben haben. Er weist die Zeiger neu zu, also ist es sicher. Lies den Code selbst :) –

0

Nr

Noch ein Tipp - nur weil man über eine Autobahn laufen, ohne getroffen werden nicht, dass sicher entweder machen.

Welche Zeiger denken Sie, dass Sie "wiederverwenden"? Ich sehe nichts nachdem es freigegeben wurde, obwohl ich annehme, dass readWords und countWords Speicher zuweisen. Wenn sie das nicht tun, haben Sie noch größere Probleme.

+1

Schleifen und wieder "Wörter" & "Wörter zählen"? –

1

kann ich nicht sagen. Es sieht sicher aus, aber ich sehe die Speicherzuweisungen nicht, also kann ich nicht sicher sein, dass Sie die richtigen Dinge freigeben.

1

Ich kann kein technisches Problem mit der Wiederverwendung sehen. Dies kann die Lesbarkeit und Wartbarkeit beeinträchtigen und die Fehlerwahrscheinlichkeit erhöhen.

1

Es ist sicher, demselben Zeiger noch etwas anderes zuzuweisen. Es ist absolut NICHT sicher, den freien Speicher wiederzuverwenden. Zu einem bestimmten Zeitpunkt würde viel Code einen Speicherblock freigeben und ihn dann so verwenden, als wäre er nicht freigegeben worden. Es verursachte massive Probleme, wenn dieser Code auf andere Betriebssysteme portiert wurde, die mit diesem Paradigma nicht so glücklich waren.

+1

es ist "befreit", kein Apostroph. Meine Güte! –

1

Es ist mir unklar, was Sie mit der Wiederverwendung meinen.

Wenn Sie dies bedeuten:

int* pInt = new int; 
*pInt = 3; 
delete pInt; 

pInt = new int; 

Dann ja, es ist sicher.

+0

Das ist was ich meine. Ich werde klären. –

+0

Ihr Punkt ist gültig, aber Sie haben ein C++ - Programm zur Veranschaulichung verwendet. Die Frage ist mit C markiert, erwähnt C++ nicht und verwendet keine C++ - spezifische Syntax. Ich empfehle Ihnen, Ihr Beispiel zu ändern, um C-Zuweisungsfunktionen zu verwenden und diesen Kommentar dann zu löschen. – Chris

0

Nicht klar, da die Zuordnung nicht angezeigt wird.

Im Allgemeinen ist es sicher, einen Zeiger so neu zuzuweisen, dass er auf etwas anderes zeigt, nachdem er freigegeben hat, auf was er zeigt.

0

Zuerst sehe ich hier kein vorzeitiges "Freigeben" (kein Apostroph!). Wo glauben Sie, dass Sie auf Daten zugreifen, die Sie bereits freigegeben haben?

Außerdem, auch wenn Sie nach dem Freigeben auf Daten zugreifen würden, hängt es vom System ab, ob dies etwas sicher ist oder nicht. Systeme können anderen Prozessen freien Speicher zur sofortigen Wiederverwendung geben, während andere Systeme, insbesondere wenn Sie die eher privaten lib-Funktionen wie malloc verwenden, nur Speicher verwenden, der nur für diesen einen Prozess verfügbar ist, also nichts wird passieren, um Speicher freizugeben, weil kein anderer Teil des Systems davon erfahren wird.