2013-04-24 13 views
5

Vecchia domanda, ma ho ancora alcuni pensieri però.Matrice in C e il suo puntatore

char * getarrmal(void) 
{ 
    char *str; 
    str = (char *)malloc(10); 
    str[0] = 'a'; 
    str[1] = 'b'; 
    str[2] = 'c'; 
    str[3] = '\0'; 
    return str; 
} 

char * getarrdef(void) 
{ 
    char *str = "hello"; 
    return str; 
} 

char * getarrfix(void) 
{ 
    char str[10] = "world"; 
    return str; 
} 

Tre funzioni. I primi due restituiranno l'indirizzo di stringa e la stringa verrà archiviata nell'heap in modo che sia possibile continuare a utilizzarlo, ad esempio la funzione main().

Nell'ultima funzione, lo str è una variabile locale e lo str restituito non può essere utilizzato.

La mia domanda è, quando torno nella funzione che sta chiamando i primi due, dovrei liberarli manualmente? È facile credere che il caso malloc sia vero, ma non sono sicuro che sia anche il caso di char * str = "ciao".

Se utilizzo getarrdef() e non restituisce il valore restituito, in qualche modo avrò perdite di memoria?

+3

Se lo hai assegnato, e non hai usato 'malloc' (o uno dei suoi cugini) per farlo, non chiami' free'. Semplice. –

risposta

3

No, si dovrebbe assolutamente non provare a liberare il secondo. È non memorizzato nell'heap, piuttosto è una stringa letterale e provare a liberarlo è un comportamento non definito. Da C++11 7.21.3.3 The free function:

... se l'argomento non corrisponde a un puntatore in precedenza restituito da una funzione di gestione della memoria , o se lo spazio è stato deallocato da una chiamata a liberare o realloc, il comportamento non è definito.

Per il primo, sì, è una buona pratica per la responsabilità della memoria allocata per passare insieme alla memoria stessa. Ciò significa che se qualcosa lo alloca e te lo concede, è responsabile della sua liberazione.

Questo è il caso anche se lo si libera passando di nuovo ad una funzione come: delarrmal() - facendo così, si è data a quella funzione la responsabilità di liberarla.

+0

Grazie per la rapida risposta :). Allora è un po 'interessante dove sono gli str memorizzati nella seconda funzione, lo stack del chiamante? – coldguy

+2

@coldguy, 'str' (il puntatore) è memorizzato nello stack nei primi due casi, e' str' (l'array) è memorizzato lì per il terzo caso. Tuttavia, ciò che il puntatore _punti a_ differisce nei primi due casi (il terzo caso è irrilevante poiché str non è un puntatore (all'interno della funzione)). Nel primo caso punta all'heap, nel secondo punta a una stringa letterale non nell'heap. – paxdiablo

+0

La funzione o il modulo che ha allocato la memoria dovrebbe liberarlo; passare del tempo per essere liberati dagli altri è un modo eccellente per perdere memoria o crash su doppio libero. Ma la cosa più importante è inchiodare e documentare la semantica della proprietà. Naturalmente, se rinunci al linguaggio obsoleto C, la proprietà passata può essere fatta in modo sicuro, come con unique_ptr di C++ 11. –

Problemi correlati