2016-10-05 3 views
1

Okay, also ich habe eine Methode, die ich anrufe. Die aufgerufene Methode gibt eine char* zurück, die innerhalb der aufgerufenen Methode zugewiesen wird. Nachdem ich die zurückgegebene char* einer neuen char* zugewiesen habe, möchte ich diese nach der Benutzung freigeben. Aber Xcode beschwert sich und gibt einen Fehler aus. Es besagt, dass das Objekt, das ich freizugeben versuche, nicht zugewiesen wird, was ich nicht bekomme, da ich sicher bin, dass ich es zuteile.c: Freigeben eines mallocated Objekt Fehler

Hier ist mein Code:

void print_r() 
{ 

    char *stateA = isActive(ruter_array[id]->flagg); 

    //print out the results etc 

    free(stateA);  <-----The program crashes here. 


} 

char * isActive(unsigned char a_flag) 
{ 
    char *ret = malloc(5); 

    if((a_flag & 1) == 1) 
    { 
     //is active 
     ret = "yes"; 
     return ret; 
    } 
    ret = "no"; 
    return ret; 

} 

Es ist nicht wichtig, zu verstehen, was das bedeutet, aber warum diese befreiende abstürzt?

+0

'isActive' gibt einen Zeiger auf die String-Konstante" yes "oder die String-Konstante" no "zurück, die keine mallocated-Objekte sind, weil sie etwas anderes sind (String-Konstanten). Es mallocates außerdem ein Objekt und gibt einen Zeiger auf dem Objekt nicht zurück. (Auch "mallocate" ist kein gebräuchlicher Begriff, aber es funktioniert) – immibis

Antwort

3
ret = "no"; 

Das überschreibt den Zeiger. Ändern zu:

strcpy(ret, "no"); 

Gleiches gilt für den Fall "yes".

Auch, wie von @DavidSchwartz aufgezeigt, ist es für Ihre Zwecke wahrscheinlich nicht notwendig, dynamisch zugewiesenen Speicher zu verwenden. Konnte einfach direkt die Stringliterale zurück:

char * isActive(unsigned char a_flag) 
{ 
    if((a_flag & 1) == 1) 
    { 
     //is active 
     return "yes"; 
    } 
    return "no"; 
} 

Und natürlich in diesem Fall der Anrufer sollte nicht free der zurückgegebene Wert.

+2

Oder verwenden Sie nicht "malloc" oder "free" überhaupt, da Sie nicht müssen. –

+0

Wow. Ich dachte, ich wüsste alles, was ich brauche, wenn es um Zeiger und Gedächtnis in c geht. Anscheinend ist das nicht der Fall. Danke. – Koen

2

Sie etwas Speicher zuzuteilen und die erste Adresse des Speichers auf den Zeiger ret, weisen aber "no" und "yes" sind Stringliterale, die statisch in einem Speicher zur Kompilierzeit Zeit gespeichert werden. Wenn Sie ret = "no" tun, ändern Sie den Zeiger, so dass es jetzt auf das erste Zeichen des Zeichenfolgenliterals "no" zeigt. Jetzt haben Sie den Zugriff auf den Speicher verloren, den Sie zugewiesen haben, und Sie haben ein Speicherleck. Aber der Absturz ist, weil Sie versuchen, Speicher freizugeben, der nicht von malloc() oder einem seiner Freunde zugewiesen wurde.

1

Sie können sogar strdup verwenden:

char * isActive(unsigned char a_flag) 
{ 
    return strdup((a_flag & 1) == 1 ? "yes" : "no"); 
} 

Wie geschrieben here der Zeiger noch durch malloc zugeordnet ist, so kann es auch befreit werden.

Verwandte Themen