2012-08-01 7 views
10

Ich versuche, ein Array mit malloc in einer Funktion zurückzukehren:Freie zugewiesenen Speicher, bevor Sie eine Funktion zurückgeben

char* queueBulkDequeue(queueADT queue, unsigned int size) 
{ 
    unsigned int i; 
    char* pElements=(char*)malloc(size * sizeof(char)); 
    for (i=0; i<size; i++) 
    { 
     *(pElements+i) = queueDequeue(queue); 
    } 
    return pElements; 
} 

Das Problem ist, dass ich frei es brauchen, weil meine MCUs Heap-Größe begrenzt ist . Aber ich möchte es zurückgeben, damit ich es in der Funktion nicht freigeben kann, oder? Kann ich den zugewiesenen Speicher außerhalb der Funktion freigeben (wo ich die Funktion anrufe). Gibt es dafür Best Practices? Vielen Dank im Voraus!

+2

Sie müssen es außerhalb der Funktion freigeben. Es gibt keine Anforderung, dass Malloc'd-Speicher in der Funktion sowieso freigegeben werden muss. – futureelite7

+0

Natürlich. Das ist der ganze Sinn von 'malloc'. Wenn Sie dies nicht tun könnten, gäbe es keinen Grund dafür, dass "malloc" jemals geschaffen wurde. –

Antwort

9

Als Speicher von malloc() ist auf dem Heap und nicht auf dem Stack, können Sie darauf zugreifen, unabhängig davon, welche Funktion sind Sie in. Wenn Wenn Sie den Speicher malloc() ed weitergeben möchten, haben Sie buchstäblich keine andere Möglichkeit, als ihn vom Aufrufer zu befreien. (In Referenzzählung Begriffe, das ist, was eine Eigentumsübertragung genannt wird.)

4

Ja, Sie können Speicher freigeben, der in einer Funktion zugewiesen ist, die Sie außerhalb der Funktion aufrufen; Genau das müssen Sie in diesem Fall tun.

Alternativen umfassen die Übergabe eines Puffers und seiner Länge an die Funktion und die Rückgabe der tatsächlichen Länge an den Aufrufer, wie es fgets tut. Dies ist möglicherweise nicht die beste Alternative, da die Anrufer Ihre Funktion in einer Schleife aufrufen müssen.

+0

Downvoter, bitte erklären Sie, was Sie mit dieser Antwort falsch finden. – dasblinkenlight

10

1) Ja, können Sie kostenlos() die malloc'ed Speicher außerhalb der Funktion

2) Nein, Sie können es nicht frei innerhalb der Funktion und haben die Daten außerhalb der Funktion übergeben, so müssen Sie 1 tun hier)

3) Wenn Sie sich über knapp Speicher betroffen sind, müssen Sie immer für Ausfall von Speicherzuordnungen überprüfen, die Sie hier nicht zu tun, die dann wahrscheinlich zu einem segfault

+1

"... ein segfault" Oder schlimmer, in einem eingebetteten System. –

+0

Ja, ich mache mir Sorgen um dieses Problem, wenn Sie einen Malloc'd-Speicher außerhalb der Funktion freigeben. Wie können Sie es beheben? – KiL

+0

@KiL das "Fix" ist, den Fall zu behandeln, in dem Ihre Speicherzuordnungsroutinen den Speicher nicht zuordnen können, der gewünscht wird, und ordnungsgemäß fehlschlagen, statt dessen, was Thread von Steuerelement ausgeführt wird, b0rkened von einem Nullzeiger. – tbert

7

führen Natürlich können Sie den Speicher freigeben, der in einer Funktion außerhalb dieser Funktion zugewiesen ist, sofern Sie i zurückgeben t.

Aber eine Alternative wäre, Ihre Funktion wie unten zu ändern, wo der Anrufer nur & Freigibt den Speicher. Dies wird inline mit dem Konzept der Funktion sein, die den Speicher zuweist, übernimmt die Verantwortung für das Freigeben des Speichers.

void queueBulkDequeue(queueADT queue, char *pElements, unsigned int size) 
{  
    unsigned int i;  
    for (i=0; i<size; i++)  
    {   
     *(pElements+i) = queueDequeue(queue);  
    }  
    return; 
} 

// Im Anrufer

char *pElements = malloc(size * sizeof(char)); 
queueBulkDequeue(queue, pElements, size); 
//Use pElements 
free(pElements);