2016-07-08 13 views
1

Angenommen, ich implementiere eine generische Stack-Struktur für eine Bibliothek. Hier ist ein Beispiel chunk:Wird zusätzlicher Speicher zugewiesen und gibt es ein Speicherleck?

typedef struct stack 
{ 
    void* key; 
    struct stack* next; 
    void*(*alloc_fn)(void*); 
} stack; 

static stack* make_stack_node(void* val, stack* next, 
           void*(*f)(void*)) 
{ 
    stack* node = malloc(sizeof(stack)); 
    if (!node) { 
     return NULL; 
    } 
    node->key = f(val); 
    node->next = next; 
    node->alloc_fn = f; 
    return node; 
} 

Der Stapel speichert einen Funktionszeiger auf eine Funktion, die Punkte, die vom Anwender eingegeben und benutzt für die Zuweisung. make_stack_node übernimmt genau diese Funktion. Beispiel für einen Stapel von int s:

static void* alloc_stack(void* val) 
{ 
    int* p = malloc(sizeof(int)); 
    *p = *(int*)val; 
    return p; 
} 

Meine Frage ist: wenn ich malloc Speicher für die node in make_stack_node und danach, wenn ich Speicher für die int in alloc_stack zuteilen, bin ich zu viel Zuteilung? Gibt es ein Speicherleck wenn ich node->key = f(val); mache?

Ich glaube so, weil ich denke, Speicher für node->key bereits bei der Vergabe von node zugeteilt worden, so, wenn ich Speicher für die int* zuweisen und ich zuweisen, dass die Brocken zu node->key, bedeutet das nicht die vorherige Sache Leck node->key war zeigt auf?

+0

Sie müssen die Zuweisungsfunktion nicht verwenden, um den Knoten zuzuordnen? Und brauchen Sie auch keine Freigabefunktion? –

Antwort

4

Sie belegen keinen Speicher für int*, Sie reservieren Speicher für int. Und nein, es gibt kein Speicherleck, vorausgesetzt, Sie geben den Speicher frei.

Wenn Sie Speicher für die stack reservieren, zeigt die key nirgendwo spezifisch. Es ist ein undefinierter Zeiger, den Sie nicht dereferenzieren dürfen. Sie müssen Speicher zuweisen, damit er genau auf die Art und Weise zeigt, wie Sie vorgehen (oder auf einen bereits zugewiesenen Speicher zeigen).

+0

Also, in einer Freigabe-Funktion von der API (nicht der Benutzer), die im Grunde über einen Stapel 's' und 'frei (s)' iteriert; ' Für alle Knoten reicht das aus, um den gesamten zugewiesenen Speicher freizugeben. Oder liege ich falsch? – DeiDei

+1

@DeiDei Sie müssen den gesamten Speicher freigeben, den Sie zuweisen, so dass Sie sowohl den Zeiger 'key' als auch den' s' freigeben müssen. –

2

Gibt es ein Speicherleck, wenn ich node->key = f(val); mache?

Wenn Sie zu node->key in make_stack_node zuweisen, node->key auf etwas zeigt nicht noch, so dass kein Speicher ist durchgesickert.

Wenn Sie node->key später in Ihrem Programm zuweisen, würden Sie anrufen müssen free(node->key) zunächst zu vermeiden, die durch alloc_stack während des Anrufs make_stack_node zugewiesenen Speicher undicht.