2016-11-01 1 views
2

Ich brauche Hilfe, um Speicher für eine Struktur freizugeben.C - Wie man free() verwendet, um eine Struktur im Speicher freizugeben?

Ich speichere einen Zeiger auf einen Speicherort in einer Variablen, aber ich möchte den Speicher nach der Verwendung freigeben. Wenn ich jedoch versuche, den Speicher freizugeben, wird nur das erste Strukturelement freigegeben (name) und age bleibt im Speicher. Mein Code kann unten gesehen werden.

int main(int argc, char **argv) 
{ 
    struct employee { 
    char *name; 
    int age; 
    }; 

    // Make pointer, employee struct and put struct in memory at pointer location 
    struct employee *employee_1; 
    struct employee new_employee; 
    new_employee.name = "Sue"; 
    new_employee.age = 26; 
    employee_1 = (struct employee *) malloc(sizeof(new_employee)); 
    (*employee_1).name = new_employee.name; 
    (*employee_1).age = new_employee.age; 

    // ... Some operations done 
    // Deallocate memory location 
    free(employee_1); 
    return 0; 
} 

Sowohl der Name und Alter des Arbeitnehmers sind auf jeden Fall an der Speicherstelle gespeichert werden, aber ich kann sie nicht freigeben beide. Ich habe das getestet, um mehr als zwei Elemente in der Struktur zu haben, und jedes Mal ist es nur das erste Element, das freigegeben wird.

Ich habe versucht, ein paar verschiedene Methoden wie jeder einzeln freigeben, falls das funktionieren würde free((*employee_1).name) aber dies wirft einen Fehler. Jede Hilfe wäre willkommen.

+1

Wie Sie herausfinden, dass 'age'„nicht freigegeben“? –

+1

[Bitte lesen Sie diese Diskussion darüber, warum nicht der Rückgabewert von 'malloc()' und Familie in 'C' umgewandelt werden soll.] (Http://stackoverflow.com/q/605845/2173917). –

Antwort

6

Nein, müssen Sie nicht ausplanenage selbst. Das ist kein "Zeiger, der von malloc() und Familie zurückgegeben wird", so dass Sie (free()) darauf nicht anrufen müssen.

Zitiert C11, Kapitel §7.22.3.3, (Hervorhebung von mir)

Die free Funktion bewirkt, dass der Raum durch ptr darauf ausgeplant werden, das heißt, für die Neuzuteilung zur Verfügung gestellt. Wenn ptr ein Nullzeiger ist, tritt keine Aktion auf. Andernfalls wird wenn das Argument nicht einen Zeiger zuvor von einer Speicherverwaltungs Funktion zurückgegeben wird, oder wenn der Raum durch einen Aufruf zu free oder realloc, das Verhalten ist nicht definiert freigegeben worden.

Auch FWIW, free() nimmt einen Zeiger, so verläuft auch die Adresse des age Membervariable wird auch falsch sein. Der zugewiesene Speicher wird automatisch vom Betriebssystem oder Speichermanager freigegeben, sobald das Programm beendet wird.

Zusammenfassend sollten Sie nur free() mit Zeigern aufrufen, die von Speicherverwaltungsfunktionen zurückgegeben werden (d. H. malloc() und Familie), das war's. Andere Zeiger, auch wenn sie Zeiger sind, müssen, wenn ihnen kein Speicher über Speicherverwaltungsfunktionen zugewiesen wird (d. H., Sie müssen einen Zeiger speichern, der von malloc() und der Familie zurückgegeben wird), nicht free() -d sein.

Zum Beispiel in Ihrem Fall, Sie rufen Sie nicht free() auf (*employee_1).name (besser gesagt, verwenden employee_1->name, bessere Lesbarkeit gibt, IMHO), wie der Zeiger nicht durch Speicherverwaltungsfunktionen zurückgeführt wird. Wenn Sie dies tun, wird undefined behavior aufgerufen.

Das sagte please see this discussion on why not to cast the return value of malloc() and family in C..

+2

Sie würden auch nicht 'name' member * in diesem Beispiel *, denn es ist ein Zeiger auf ein String-Literal –

+0

@ WeatherVane Sir, versucht, ein wenig zu klären, ist das würdig? –

+0

Ja, ich habe schon UV gegeben. Von meinem anderen Kommentar habe ich über den Fall nachgedacht, wo Speicher für einen Namen von 'malloc' kommt und dieser Zeiger in ähnlicher Weise in eine andere' struct' kopiert wurde: Es könnte die Gefahr bestehen, dass dieser Zeiger später * zweimal * freigegeben wurde, wenn er dort war war nur eine Zuteilung. –

1

Wenn Sie reservierten Speicher dynamisch für *name Dann:

free(employee->name); 
+0

Sie würden nicht im OP-Fall, sondern provozieren undefiniertes Verhalten, als was es auf den Speicher zeigt, die nicht dynamisch von 'malloc()' & Friends zugewiesen wurde. – alk

+0

Achten Sie darauf, dass der Zeiger im geposteten Code in eine andere 'Struktur' kopiert wird. Wenn der Speicher aus "malloc" stammt, besteht die Gefahr, dass dieser Zeiger später zweimal freigegeben wird, wenn nur eine Zuweisung vorhanden war. –

Verwandte Themen