0

Ich bin auf der Suche nach der bequemsten/besten/intelligentesten Möglichkeit für mehrere Speicherfreigabe. Nicht ganz sicher, ob das beste Erklärung ist da draußen, aber hier ist ein Beispiel, das zeigen, was ich tun möchte:Die bequemste Möglichkeit, mehrere Speicherzeiger aufzuheben?

void func() 
{ 
    int* ptr1 = malloc(1); 
    if(ptr1 == NULL) 
    { 
     //... 
    } 

    int* ptr2 = malloc(1); 
    if(ptr2 == NULL) 
    { 
     //... 
     free(ptr1); 
    } 

    int* ptr3 = malloc(1); 
    if(ptr3 == NULL) 
    { 
     //... 
     free(ptr2); 
     free(ptr1); 
    } 

    //code... 
} 

Das einzige, was bis zu meinem Sinn kommt Array mit Fahnen gefüllt, wenn das Flag angehobene besondere Erinnerung muss befreit werden. Gibt es einen anderen bequemeren Weg, dies zu tun? Sie können sich vorstellen, wie oft ich free() wiederholen muss, wenn mehr malloc() -ing benötigt wird.

+1

sie in einem Array Setzen der NULL beendet/initialisiert und iteriert dieses Array. –

+0

Ich hoffe, es gibt eine andere Möglichkeit, das zu tun, außer mit einem Array. –

+1

'ptr1 * = malloc (1);' ist kompletter Unsinn. Bitte posten Sie echten Code. – joop

Antwort

3

Was Sie auf dem Laufenden ist eine gängige Praxis für die Fehlerbehandlung und Ressourcenfreigabe in einer Funktion, erwerben Sie mehrere Ressourcen und falls ein Fehler aufgetreten ist, müssen Sie diejenigen, die zuvor erworben wurden freizugeben, gibt es nichts falsches, tun Sie es nur eins nach dem anderen.

void func(void) { 
    void *ptr1 = NULL; 
    void *ptr2 = NULL; 
    void *ptr3 = NULL; 

    ptr1 = malloc(SIZE); 
    if (!ptr1) goto end; 

    ptr2 = malloc(SIZE); 
    if (!ptr2) goto end; 

    ptr3 = malloc(SIZE); 
    if (!ptr3) goto end; 

    // do your work with the buffers 

end: 
    free(ptr1); 
    free(ptr2); 
    free(ptr3); 
} 
+0

@ user694733, das würde den Code davon abhängig machen, dass das Verhalten (die Implementierung) von 'free' beim Freigeben eines NULL-Zeigers nicht abstürzt. Ich stimme dem ursprünglichen, defensiven und korrekten Ansatz zu, ptr vor dem Aufruf von NULL zu testen. –

+1

@PaulOgilvie C-Standard (aus Entwurf N1570) Kapitel 7.22.3.3 sagt: * "Die freie Funktion bewirkt, dass der Raum, auf den ptr verweist, freigegeben wird, dh für weitere Zuweisung verfügbar ist. Wenn ptr ein Nullzeiger ist, nein Aktion tritt auf. ... "* – user694733

+0

@ user694733, Standards ändern sich. Vergangene Standards hatten das nicht. Der Code ist nicht defensiv. Es verursacht möglicherweise unnötige Funktionsaufrufe. Mein Argument basiert vielleicht auf der Meinung. –

3

Sie können eine array of pointers verwenden und die Anzahl der malloc s gezählt halten. Und verwenden Sie eine gemeinsame freie Funktion zu free sie alle. Wie,

void func() 
{ 
    char* ptr[10]; 
    int n = 0, i; 

    for(i = 0; i < 10; i++) 
     ptr[i] = NULL; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
    } 
    n++; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
     custom_free(ptr1, n); 
    } 
    n++; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
     custom_free(ptr, n); 
    } 
    n++; 
    //code... 
} 

Und die custom_free() kann wie etwas sein,

void custom_free(char* ptr[], int n) 
{ 
    int i; 

    for(i = 0; i <= n; i++) 
     free(ptr[i]); 
} 
0

Eine alternative Möglichkeit ist es, alle benötigten Speichers in einem großen Teil zuzuteilen, und Teile davon als p0, p1, p2 behandeln:

void worker(void) 
{ 
#define N_ELEM 123 
int *work_mem; 
int *p0,*p1,*p2; 

work_mem = malloc (3* N_ELEM * sizeof *work_mem); 
if (!work_mem) { OMG(); return; } 

p0 = work_mem, p1= work_mem + N_ELEM, p2 = work_mem + 2 * N_ELEM; 

     /* do useful stuff here with work_mem 
     ** , possibly via p0,p1,p2 
     */ 

free(work_mem); 
} 
+0

Während dies funktioniert, müssen Sie manuell sicherstellen, dass alle Zeiger richtig ausgerichtet sind. Es wäre sicherer, alle Variablen in einer einzigen Struktur zu platzieren und den Compiler die Ausrichtungsdetails sortieren zu lassen. – user694733

+0

Ja, aber Sie müssen auch im Originalfall auf Korrektheit achten. [Das 'int * p = malloc (1);' in der (korrigierten) Frage ist nicht geeignet, um zum Beispiel ein einziges int zu speichern.] – joop

+0

True, aber das ist ein Problem mit der Größe, nicht der Ausrichtung. Aber auch das Größenproblem ist einfacher mit struct zu handhaben, vorausgesetzt, die benötigte Größe ist statisch wie in Ihrem Beispiel: 'CombinedType * data = malloc (sizeof * data);' – user694733

Verwandte Themen