2016-09-25 5 views
0

Ich versuche, Speicherverluste in meinem Code zu vermeiden. Ich muss pElement, Zeile und pSecond freigeben, ohne die Werte in pImage zu verlieren. Weil ich diese Werte in meiner Druckfunktion drucken muss.Wie kann ich einen struct Zeiger, den ich brauche

Meine Add-Funktion enthält struct GraphicElement * pElements ;, struct GraphicElement * pSecond ;, struct Punkt point ;.

Ich reservieren Speicher mit Malloc für jede Struktur und fügen Sie dann die Werte und dann übergebe ich die endgültigen Werte in pImage. Alle meine anderen Funktionen funktionieren perfekt neben der Tatsache, dass ich immer 3 Speicherlecks habe. Weil ich nicht frei habe (pSekunde); .... frei (pElement) ... frei (Linie);

Wenn ich versuche, sie zu befreien, bevor meine Funktion beendet und die Werte in pImage übergeben. Meine Werte werden alle gelöscht.

Wie kann ich diese Werte innerhalb meiner Add-Funktion lokal freigeben?

struct Point 
{ 
    int x, y; 
}; 

struct Line 
{ 
    Point start; 
    Point end; 
}; 

struct GraphicElement 
{ 
    enum{ SIZE = 256 }; 
    unsigned int numLines; //number of lines 
    Line* pLines; //plines points to start and end 
    char name[SIZE]; 
}; 

typedef struct 
{ 
    unsigned int numGraphicElements; 
    GraphicElement* pElements; //the head points to pLines 
} VectorGraphic; 

void InitVectorGraphic(VectorGraphic*); //initializes pImage->pElement 
void AddGraphicElement(VectorGraphic*); //Used to add 
void ReportVectorGraphic(VectorGraphic*); // prints pImage contents 
void CleanUpVectorGraphic(VectorGraphic*); //deallocates memory 
+1

Es klingt wie Ihr pImage diese Werte verwendet. Warum müssen sie in deinem Add freigegeben werden? Warum nicht sie in Ihrer 'CleanUpVectorGraphic' Funktion freigeben? – NullEntity

+1

Wenn Sie einen Strukturzeiger benötigen, warum möchten Sie ihn dann an erster Stelle freigeben? IMO, Sie sollten erklären, was Sie tun wollen, da ich nicht verstehe, was Sie erreichen wollen. –

+1

@Disillusioned könnte ich auf diese Strukturen von einer anderen Funktion zugreifen? Ich weiß, ich kann befreien (pImage); und alle seine Inhalte in einer Schleife. Aber was ist mit line, pSecond und pElement? Wie würde ich von der Aufräumfunktion auf sie zugreifen? – Calidreaminn

Antwort

1

Wie kann ich diese Werte in meiner Add-Funktion lokal befreien?

Es ist nicht möglich, einen lokal zugewiesenen Speicher explizit freizugeben. Noch zu lokal frei etwas Speicher. Nach dem Freigeben kann auf einen Speichersteckplatz nicht mehr zugegriffen werden und die darin gespeicherten Daten gehen verloren.

In C haben Sie zwei Optionen, um Speicher zuzuordnen: Sie können ihn auf dem Heap oder auf dem Stack zuweisen. Auf die im Heap reservierten Speichersteckplätze kann global zugegriffen werden, bis sie explizit freigegeben werden. Die auf dem Stack reservierten sind nur gültig, solange Sie in dem Kontext bleiben, in dem sie erstellt wurden.

Angenommen, Sie den folgenden Code ausführen:

void func() 
{ 
    int x = 3; // [2] 
    int * p = & x; // [3] 
} 

int main() 
{ 
    func();   // [1] 

    // [4] 
    return 0; 
} 

Die Anweisung [2] auf dem Stack etwas Speicher zuteilen wird. Die zweite ([3]) wird das gleiche tun und wird die Adresse der ersten Variablen in dem neuen Speichersteckplatz speichern. Nachdem die Funktion zurückgegeben wurde(), wird dieser Speicher freigegeben. Grafisch hier ist, was passiert: So

 Context STACK Address 
       +---------+  
       |   | 0xa1 
     main |   | 0xa0    
       +---------+  

[1]   +---------+ 
=====>  |   |   
     func |   | 0xa2   
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[2]   +---------+ 
=====>  |   | 
     func | 3  | 0xa2 <-- x 
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[3]   +---------+ 
=====>  | 0xa2 | 0xa3 <-- p 
     func | 3  | 0xa2 <-- x 
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[4]   +---------+ 
=====>  |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

, wenn ich in einer Funktion malloc verwenden. Sobald ich die Funktion existiere, wird der zugewiesene Speicher auf dem Heap automatisch freigegeben.

Es ist das Gegenteil. Wenn Sie eine Funktion wie malloc verwenden, wird der Speichersteckplatz auf dem Heap zugewiesen. Also, wenn wir die Linie [3] oben zu so etwas wie

int * p = malloc(sizeof(int)); // [3] 

Der Speicher auf dem Stapel reserviert ändern befreit werden, wie Sie die Funktion verlassen werden, aber der Speicher auf dem Heap reserviert bleiben zugewiesen und wird noch zugänglich sein bis du es frei hast. Grafisch:

            HEAP  Address Free (y/n) 
               +---------+ 
               |   | 0xb4 - Yes 
               |   | 0xb3 - Yes 
               +---------+ 
     Context STACK Address    
[3]   +---------+      +---------+ 
=====>  | 0xb4 | 0xa3 <-- p   |   | 0xb4 - No 
     func | 3  | 0xa2 <-- x   |   | 0xb3 - Yes 
       +---------+      +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[4]   +---------+      +---------+ 
=====>  |   | 0xa1     |   | 0xb4 - No !!! Leak !!! 
     main |   | 0xa0     |   | 0xb3 - Yes 
       +---------+      +---------+ 

Wie Sie sehen können, nachdem Sie die Funktion verlassen, haben Sie einen Speicherverlust, wie Sie haben keinen Zeiger auf den dynamisch zugewiesenen Speicher.Eine Möglichkeit, dies zu vermeiden, besteht darin, den Zeiger zurückzugeben (um die Adresse des neuen Speichersteckplatzes an die aufrufende Funktion zu übergeben) oder sie irgendwo zu speichern, um sie später freizugeben. Es ist auch möglich, den Speicher vor dem Aufruf der Funktion zu reservieren und als Parameter an die Funktion zu übergeben. Es hängt wirklich von Ihrer Anwendung ab.

Verwandte Themen