2010-10-08 15 views
6

Ich verstehe nicht, warum in diesem Code, der Aufruf von „frei“ einen Segmentierungsfehler verursachen:Malloc, frei und Segmentierungsfehler

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

char *char_arr_allocator(int length); 

int main(int argc, char* argv[0]){ 

    char* stringa = NULL; 
    stringa = char_arr_allocator(100); 
    printf("stringa address: %p\n", stringa); // same address as "arr" 
    printf("stringa: %s\n",stringa); 
    //free(stringa); 

    return 0; 
} 

char *char_arr_allocator(int length) { 
    char *arr; 
    arr = malloc(length*sizeof(char)); 
    arr = "xxxxxxx"; 
    printf("arr address: %p\n", arr); // same address as "stringa" 
    return arr; 
} 

Kann es mir jemand erklären?

Danke, Segolas

+0

haben auch einen Blick auf http://www.hpl.hp.com/personal/Hans_Boehm/gc/ Es ist sehr schön. –

Antwort

14

Sie Zuweisen des Speichers mit malloc richtig:

arr = malloc(length*sizeof(char)); 

dann tun Sie dies:

arr = "xxxxxxx"; 

diese "xxxxxxx"arr Punkt an die Adresse des Stringliteral verursacht, undichte Ihr malloc ED-Speicher. Und auch Aufruf free auf Adresse von String-Literal führt zu undefiniertem Verhalten.

Wenn Sie kopieren wollen die Zeichenfolge in den zugewiesenen Speicher zu verwenden strcpy als:

strcpy(arr,"xxxxxxx"); 
+1

Sie sind direkt auf dem UB-Teil: Aufruf von 'free' mit einem beliebigen Zeigerwert (anders als' NULL') nicht von 'malloc' oder' realloc' ergibt undefiniertes Verhalten. – schot

2

Die dritte Zeile von char_arr_allocator() tilgt Ihr malloc() Ergebnis und ersetzt es mit einem Stück von statischen Speichern in der Datenseite. Rufen Sie free() auf diesem explodiert.

Verwenden Sie str[n]cpy(), um stattdessen das Zeichenfolgenliteral in den Puffer zu kopieren.

2

Wenn Sie eine konstante Zeichenfolge in C schreiben, z. B. "xxxxxx", wird dieser String direkt in die ausführbare Datei geschrieben. Wenn Sie in Ihrer Quelle darauf verweisen, wird es durch einen Zeiger auf diesen Speicher ersetzt. So können Sie die Zeile

arr = "xxxxxxx"; 

Behandlung arr als Zahl als so etwas wie lesen:

arr = 12345678; 

Wo diese Zahl ist eine Adresse. malloc hat eine andere Adresse zurückgegeben, und Sie haben diese weggeworfen, als Sie arr eine neue Adresse zugewiesen haben. Sie erhalten einen segfault, weil Sie versuchen, einen konstanten String freizugeben, der sich direkt in Ihrer ausführbaren Datei befindet - Sie haben ihn nie zugewiesen.

0

Sie setzen arr auf den Rückgabewert malloc(), der korrekt ist. Aber Sie weisen es dann neu zu, um auf die String-Konstante "xxxxxxx" zu zeigen. Wenn Sie also free() aufrufen, fordern Sie die Laufzeitumgebung auf, eine String-Konstante freizugeben, die den seg-Fehler verursacht.