und ich weise Raum durch malloc zu und fülle ihn mit einigen Werten
PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
strcpy(testPerson->firstName, "Jack");
strcpy(testPerson->surName, "Daniels");
Was ist der richtige und sichere Weg, um den gesamten von dieser Struktur belegten Speicher freizugeben? Ist “kostenlos (Testperson);” genug oder muss ich das Attribut jeder Struktur einzeln freigeben?
Das führt mich zu einer anderen Frage – wie werden Strukturen im Gedächtnis gespeichert? Ich habe ein seltsames Verhalten bemerkt – wenn ich versuche, die Strukturadresse zu drucken, ist sie gleich der Adresse des ersten Attributs.
Das bedeutet, dass dieses free(testPerson) gleich diesem free(testPerson->firstName) sein sollte;
und das ist nicht, was ich tun möchte.
Vielen Dank
Eine gute Faustregel: Für jeden Malloc braucht man genau einen freien (nicht mehr und nicht weniger).
– Chris Eberle
27. November 2012 um 18:40 Uhr
Manchmal möchten Sie möglicherweise früher freigeben, und dies erfordert möglicherweise mehr Freizeichen (da einige in bedingten if-Anweisungen enthalten sind) als Malloc-Zeichen
– Kodierer
13. Juli um 17:51 Uhr
Omkant
Einfache Antwort: free(testPerson) reicht .
Denken Sie daran, dass Sie verwenden können free() nur wenn Sie Speicher mit zugewiesen haben malloc, calloc oder realloc.
In Ihrem Fall haben Sie nur einen Malloced-Speicher für testPerson das ist also ausreichend zu befreien.
Wenn Sie verwendet haben char * firstname , *last surName dann müssen Sie in diesem Fall den Speicher zugewiesen haben, um den Namen zu speichern, und deshalb mussten Sie jedes Mitglied einzeln freigeben.
Hier ist auch ein Punkt, an dem es in umgekehrter Reihenfolge sein sollte; Das bedeutet, dass der Speicher für Elemente später zugewiesen wird free() es gibt dann zuerst den Zeiger auf Objekt frei.
Wenn Sie jedes Element freigeben, können Sie die unten gezeigte Demo sehen:
typedef struct Person
{
char * firstname , *last surName;
}Person;
Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct
ptrobj->firstname = malloc(n); // memory allocation for firstname
ptrobj->surName = malloc(m); // memory allocation for surName
.
. // do whatever you want
free(ptrobj->surName);
free(ptrobj->firstname);
free(ptrobj);
Der Grund dafür ist, wenn Sie die freigeben ptrobj zuerst, dann gibt es ein Speicherleck, das der Speicher ist, der von zugewiesen wird firstname und suName Zeiger.
Beim letzten Satz liegt das Speicherleck wahrscheinlich an der Strukturauffüllung.
– Schasch
28. November 2012 um 10:05 Uhr
Nein. Ich sagte, dass wenn free(ptrobj) ist dann erledigt firstname und suname Zeiger sind die Mitglieder auf dem Haufen, der weg ist, also der Speicher, der von zugewiesen wurde firstname und suname wird nicht befreit, denn um es zu befreien, müssen Sie schreiben free(firstname) aber vorname existiert nicht mehr ..hopw du hast es
– Omkant
28. November 2012 um 10:11 Uhr
Viswestn
Zuerst sollten Sie wissen, wie viel Speicher zugewiesen wird, wenn Sie Speicher im folgenden Fall definieren und zuweisen.
1) Die Größe von (PERSON) gibt jetzt 8 Bytes zurück (ohne Auffüllen)
2) Sie müssen Speicher für firstName und surName zuweisen, indem Sie malloc() oder calloc() aufrufen. wie
testPerson->firstName = (char *)malloc(100);
3) Befreien Sie zuerst die Mitglieder in der Struktur, bevor Sie die Struktur befreien. dh free(testPerson->firstName); frei(Testperson->Nachname); kostenlos (Testperson);
Vielen Dank. Ich muss mich also nur um die dynamischen Variablen kümmern, wie bei Funktionen
– Benutzer10099
27. November 2012 um 19:05 Uhr
S Dao
free ist nicht genug, free markiert den Speicher nur als unbenutzt, die Strukturdaten bleiben dort, bis sie überschrieben werden. Stellen Sie den Zeiger sicherheitshalber auf NULL nach free.
Ex:
if (testPerson) {
free(testPerson);
testPerson = NULL;
}
struct ist ähnlich wie ein Array, es ist ein Speicherblock. Sie können über seinen Offset auf das Strukturmitglied zugreifen. Das Mitglied der ersten Struktur wird bei Offset platziert 0 Die Adresse des Members der ersten Struktur ist also dieselbe wie die Adresse der Struktur.
Weil Sie das definiert haben struct als bestehend aus char Arrays, die beiden Strings sind die Struktur und die Befreiung der struct ist ausreichend, noch gibt es eine Möglichkeit, die zu befreien struct aber behalten Sie die Arrays. Für diesen Fall würden Sie so etwas tun wollen struct { char *firstName, *lastName; }aber dann müssen Sie Speicher für die Namen separat zuweisen und die Frage behandeln, wann Sie ihn freigeben das Erinnerung.
Nebenbei: Gibt es eine Grund Sie möchten die Namen nach dem beibehalten struct wurde befreit?
Auf diese Weise müssen Sie die Struktur nur freigeben, da die Felder Arrays mit statischen Größen sind, die als Teil der Struktur zugewiesen werden. Dies ist auch der Grund dafür, dass die angezeigten Adressen übereinstimmen: Das Array ist das Erste in dieser Struktur. Wenn Sie die Felder als char * deklariert haben, müssten Sie sie auch manuell mallocieren und freigeben.
djna
Mallocs und Frees müssen gepaart werden.
malloc schnappte sich einen Speicherplatz, der groß genug für Person war.
Wenn Sie freigeben, teilen Sie malloc mit, dass das Stück Speicher, das “hier” beginnt, nicht mehr benötigt wird, es weiß, wie viel es zugewiesen hat, und gibt es frei.
Ob Sie anrufen
free(testPerson)
oder
free(testPerson->firstName)
Alles, was free() tatsächlich erhält, ist eine Adresse, dieselbe Adresse, es kann nicht sagen, welche Sie angerufen haben. Ihr Code ist jedoch viel klarer, wenn Sie free(testPerson) verwenden – er stimmt eindeutig mit malloc überein.
Sie können keine Typen freigeben, die nicht dynamisch zugewiesen wurden. Obwohl Arrays syntaktisch ähnlich sind (int* x = malloc(sizeof(int) * 4) kann genauso verwendet werden int x[4] ruft an free(firstName) würde wahrscheinlich einen Fehler für letzteres verursachen.
Nehmen Sie zum Beispiel diesen Code:
int x;
free(&x);
free() ist eine Funktion, die einen Zeiger aufnimmt. &x ist ein Zeiger. Dieser Code kann kompiliert werden, obwohl er einfach nicht funktioniert.
Wenn wir vorgeben, dass der gesamte Speicher auf die gleiche Weise zugewiesen wird, x wird in der Definition “zugewiesen”, in der zweiten Zeile “freigegeben” und nach dem Ende des Geltungsbereichs wieder “freigegeben”. Sie können dieselbe Ressource nicht zweimal freigeben; es wird Ihnen einen Fehler geben.
Dies erwähnt nicht einmal die Tatsache, dass Sie aus bestimmten Gründen den Speicher unter möglicherweise nicht freigeben können x ohne das Programm zu schließen.
tl; dr: Befreie einfach die struct und es wird dir gut gehen. Nicht Rufen Sie kostenlos auf Arrays an; Rufen Sie es nur auf dynamisch zugewiesenem Speicher auf.
Außerdem werden Variablen normalerweise nicht auf dem Heap allokiert, deshalb free(&x) könnte schon scheitern.
– Nikolas R
27. November 2012 um 18:49 Uhr
Ich bin versucht, für wirklich nachlässigen Sprachgebrauch abzustimmen, aber ich möchte einen neuen Benutzer nicht davon abhalten, etwas zu posten. Es gibt jedoch zwei eklatante Fehler, auf die hingewiesen werden muss: Es ist nicht klar, was Sie mit “Arrays werden durch Zeiger dargestellt” meinen, und es ist nicht klar, was “gültiger Code” bedeutet. Ganzzahl x; kostenlos(&x); ist kein gültiger Code.
– MK.
27. November 2012 um 19:01 Uhr
@MK.: Vielen Dank für den Hinweis auf diese Fehler; Ich habe versucht herauszufinden, wie man es richtig formuliert, weil ich sicherstellen wollte, dass ich keine Sprache verwende, die für C++ und nicht für C gilt. Es ist jetzt viel klarer.
Eine gute Faustregel: Für jeden Malloc braucht man genau einen freien (nicht mehr und nicht weniger).
– Chris Eberle
27. November 2012 um 18:40 Uhr
Manchmal möchten Sie möglicherweise früher freigeben, und dies erfordert möglicherweise mehr Freizeichen (da einige in bedingten if-Anweisungen enthalten sind) als Malloc-Zeichen
– Kodierer
13. Juli um 17:51 Uhr