2010-10-08 14 views
6

non capisco il motivo per cui, in questo codice, la chiamata a "libero" causa un errore di segmentazione:Malloc, libero e segmentazione colpa

#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; 
} 

Qualcuno può spiegare a me?

Grazie, Segolas

+0

anche dare un'occhiata a http://www.hpl.hp.com/personal/Hans_Boehm/gc/ è davvero carino. –

risposta

14

si assegnano la memoria utilizzando malloc correttamente:

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

allora si esegue questa operazione:

arr = "xxxxxxx"; 

questo farà sì che arr punto l'indirizzo della stringa letterale "xxxxxxx", perdite la tua memoria malloc ed. E anche chiamando free sull'indirizzo di stringa letterale porta a comportamento non definito.

Se si vuole copia la stringa in dell'uso memoria allocata strcpy come:

strcpy(arr,"xxxxxxx"); 
+1

Hai ragione da parte UB: Chiamare 'free' con qualsiasi valore del puntatore (diverso da' null') non da '' malloc' o realloc' dà un comportamento indefinito. – schot

2

La terza linea di char_arr_allocator() spazza via il risultato malloc() e lo sostituisce con un pezzo di memoria statica nella pagina di dati. Chiamando free() su questo scoppi.

Utilizzare str[n]cpy() per copiare invece la stringa letterale nel buffer.

2

Quando si scrive una stringa costante in C, ad esempio "xxxxxx", ciò che accade è che quella stringa va direttamente nell'eseguibile. Quando fai riferimento ad esso nella tua fonte, viene sostituito con un puntatore a quella memoria. Così si può leggere la riga

arr = "xxxxxxx"; 

Trattare arr come un numero come qualcosa di simile:

arr = 12345678; 

Dove quel numero è un indirizzo. malloc ha restituito un indirizzo diverso, e lo hai buttato via quando hai assegnato un nuovo indirizzo a arr. Stai ottenendo un segfault perché stai provando a liberare una stringa costante che è direttamente nel tuo eseguibile - non l'hai mai assegnata.

0

Si sta impostando arr sul valore restituito di malloc(), che è corretto. Ma lo stai riassegnando per puntare alla costante di stringa "xxxxxxx". Così, quando si chiama free(), si sta chiedendo il runtime per liberare una stringa costante, che provoca l'errore seg.