2012-04-08 4 views
5

Se vorrei scrivere:Liberare le stringhe in C

char *a=malloc(sizeof(char)*4); 
a="abc"; 
char *b="abc"; 

ho bisogno di liberare questa memoria, o è fatto da mio sistema?

+0

Un ulteriore commento è che credo che non sia necessario sizeof (char) poiché in tutte le implementazioni che ho visto finora è sempre 1 byte. So malloc (4); sarebbe sufficiente – Lefteris

+1

@Lefteris in realtà l'implementazione sopra è buona. Sebbene la maggior parte dei sistemi utilizzi un byte byte, l'implementazione sopra lascia chiaro ciò che viene assegnato, e se il codice viene modificato per utilizzare unichar, che di solito sono due byte, sarà più facile cambiarlo. – ThomasW

+0

@ThomasW Temo di non essere sicuro di cosa sia esattamente un unichar ma suppongo che abbia a che fare con unicode. Una rapida ricerca su google suggerisce oggettivo-c che è un'altra lingua: P Ma i caratteri unicode in genere non vengono chiamati solo caratteri. Ad esempio, prendi caratteri larghi wchar_t. Potrebbe essere sbagliato, ma questo è quello che ho visto finora con le implementazioni che ho affrontato con – Lefteris

risposta

10

Nella tua situazione non avrai modo di liberare la memoria allocata dinamica perché stai perdendo il riferimento ad essa.

Prova questo fuori:

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

int main() 
{ 
    char *a=(char*)malloc(sizeof(char)*4); 
    printf("Before: %p\n",a); 
    a = "abc"; 
    printf("After: %p\n",a); 
    free(a); 
    char *b = "abc"; 

    return 0; 
} 

Otterrete

Before: 0x100100080 
After: 0x100000f50 

Vedrete che i due puntatori sono diversi.Questo perché la stringa letterale "abc" è inserito nel settore dei dati dei file binari e quando lo fai

a = "abc" 

si stanno cambiando il puntatore del a per puntare alla stringa letterale costante "abc" e si sta perdendo la memoria precedentemente allocato. Chiamare free su a non è più corretto, solo perché non punta più a un indirizzo valido assegnato dinamicamente più. Per preservare il puntatore e essere in grado di liberarlo si dovrebbe copiare la stringa con

strncpy(a, "abc", 4) 

Questo effettivamente Copiate il codice letterale al metodo allocata dinamicamente, preservando il puntatore originale.

+2

strcpy è la radice di molti buffer overflow. Usa invece strncpy. – rampion

+0

Hai ragione, stavo considerando questo caso specifico, lascia che lo modifichi – Jack

+0

@rampion Solo per curiosità, perché dici questo? Perché strcpy copia i byte strlen (sorgente) che potrebbero non essere sempre controllati rispetto alla dimensione del buffer della destinazione? O capisco male? – Lefteris

0

sì, è necessario liberare la memoria restituita da malloc.

3

Non è possibile assegnare stringa in questo modo con C

a = "abc" 

Tuttavia, se si utilizza malloc allora dovete usare free, come questo

free(a); 

Ma attenzione, se si utilizza free(a) nella vostra esempio ottieni un errore Perché dopo il malloc si modifica il valore del puntatore a nella stringa statica "abc"; Quindi il prossimo free(a) tenta di liberare un dato statico. E ottieni l'errore.

4

Qui c'è una perdita di memoria. Quando si imposta a="abc", non si sta riempiendo la memoria appena assegnata, si sta riassegnando il puntatore a puntare alla stringa statica "abc". b punta alla stessa stringa statica.

Quello che vuoi invece è strncpy(a, "abc", 4), che copierà il contenuto di "abc" nella memoria che hai assegnato (a quale punto a).

Quindi è necessario liberarlo al termine.

2

Risposta semplice sì, no. Anche il tuo codice è bacato.

risposta concreta:

char *a=malloc(sizeof(char)*4); 

si alloca la memoria così si dovrebbe liberarlo.

a="abc"; 

Questo assegna un puntatore a una stringa costante al vostro char* a, così facendo si perde il puntatore alla memoria allocata nella prima riga, si dovrebbe stringhe costanti mai liberi.

Utilizzare strcpy(a,"abc"); anziché a="abc"; per spostare la stringa nella memoria allocata.

+2

strcpy è la radice di molti buffer overflow. Usa invece strncpy. – rampion

0

Sì, causerà una perdita di memoria. Il sistema non è stato in grado di gestire il caso.