2016-03-27 9 views
0
freigeben

Ich schreibe ein C-Programm, aber ich bekomme einige Speicherfehler, also habe ich beschlossen, ein kleines Programm zu machen, um zu sehen, wann und wie Speicher freigegeben werden.wie ich Speicher in C

Mein Beispiel:

int main() { 
    char *a=malloc(5); 
    a="mama"; 
    char *b=malloc(strlen(a)); 
    printf("%s\n",a); 
    strcpy(b,a); 
    free(a); 
    printf("%s\n",b); 
    return 0; 

}

hier ich erhalte eine Fehlermeldung:

* Fehler in `./a ': frei(): ungültige Zeiger: 0x0000000000400757 *

aber wenn ich ch ange nur eine Zeile:

int main() { 
    char *a=malloc(5); 
    strcpy(a,"mama"); 
    char *b=malloc(strlen(a)); 
    printf("%s\n",a); 
    strcpy(b,a); 
    free(a); 
    printf("%s\n",b); 
    return 0; 

}

Mein zweites Programm gut funktioniert, warum also in dem ersten Fehler ich erhalte? ich hoffe, dass Sie mir erklären können, warum.

In My Real Programm, das ich bin, wie das zu tun:

char * getDate(){ 

    char *date=malloc(5); 
    //some instructions here 
    return date; 
} 


int main() { 
    char *a=malloc(5);//im sure that a will not exceed 5 bytes 
    a=getDate(); 
    return 0; 
} 

Es ist nur ein kleines Beispiel, und ich weiß nicht, wo Speicher frei .so, wie und wo ich Speicherplatz freigeben kann, habe ich Frei Datum oder den Char Zeiger?

Edited zweite Zeit:

void getDate(char *a){ 
     //some instructions here 
    strcpy(a,"haha"); 

} 
int main() { 
     char *a=malloc(5); 
      getDate(a); 
      int i= strlen(a); 
      printf("%s and the size is :%d\n",a,i); 
      free(a); 
      return 0; 
} 

was sind die Regeln, ich habe zu folgen Speicherfehler zu vermeiden.

vielen dank.

+1

'char * a = malloc (5)' - verwende keine magischen Zahlen. – user8

+2

Sie reservieren nicht genügend Speicher für 'b'. Denken Sie daran, 'strlen' zählt das abschließende Null-Byte nicht, daher müssen Sie eins hinzufügen, wenn Sie' b' zuweisen. –

+0

[seufz] Leck in den ersten beiden Zeilen :( –

Antwort

4

In der Zeile:

char *a=malloc(5); 

Sie ordnen a mit der Adresse eines dynamisch Speicherblock zugewiesen, aber dann in der Zeile:

a="mama"; 

Sie es neu zuweisen mit der Adresse die Literal-String-Konstante "mama". Wegwerfen der Zeiger auf den dynamisch zugewiesenen Block, so dass, wenn Sie

nennen
free(a); 

a ist nicht mehr ein gültiger Heap-Speicher-Block und nicht aufgehoben werden kann.

Strings (und Arrays im Allgemeinen) in C sind keine Daten erster Klasse und können nicht zugewiesen werden. Sie sollten ersetzen:

a="mama"; 

mit

strcpy(a, "mama") ; 

Die Zuordnung der Zeigerwert setzt - es nicht Kopie "mama" an die Speicherpunkte durch a.Der Aufruf strcpy() andererseits kopiert die Zeichenfolge in den dynamischen Speicherblock , auf den von a verwiesen wird.

In Ihrem zweiten Codefragment "lecken" Sie den Speicher, der in main() zugewiesen wurde, da Sie a zugewiesen haben, ohne den ursprünglichen Block freizugeben. Obwohl in Ihrem Beispiel a nicht frei ist, bleibt es frei, da die Zuweisung in GetDate() dynamisch ist. Als Codierungsstil ist das dynamische Zuweisen von Speicher in einer Funktion und das Zurückgeben ihres Zeigers eine schlechte Idee, da es die Verantwortung des Aufrufers feststellt, dass der Speicher dynamisch zugeordnet wurde und frei sein muss und Speicherlecks einleitet.

+0

danke für die Antwort, danke, Aber was denkst du, wenn du eine Methode verwendest, um einen Char-Zeiger zu retentieren, ist es das gleiche? Und wo ich den Speicher in der Hauptmethode oder in der aufgerufenen Methode freigeben muss, siehe die letzte Seite –

+0

@jeanjack: Ich habe eine Anmerkung dazu, aber in der Sekunde, die Sie nicht einmal kostenlos() anrufen, so dass Sie nicht vergleichen, für-wie-gleich. Die Fehlermeldung zeigt deutlich, dass es der Aufruf von free() ist, die zur Laufzeit fehlschlägt , in der zweiten 'a' bleibt frei, weil es einen dynamisch zugewiesenen Block zugewiesen ist. Beachten Sie auch, dass die Laufzeit nicht erforderlich ist, um einen Fehler auszugeben, wenn free() fehlschlägt - das ist abhängig von der Implementierung. – Clifford

+0

danke, eine klare Antwort, ich habe meinen zweiten pgm bearbeitet, ich denke es ist gut Weg zur Speicherfreigabe. –