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?
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?
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.
strcpy è la radice di molti buffer overflow. Usa invece strncpy. – rampion
Hai ragione, stavo considerando questo caso specifico, lascia che lo modifichi – Jack
@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
sì, è necessario liberare la memoria restituita da malloc.
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.
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.
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.
strcpy è la radice di molti buffer overflow. Usa invece strncpy. – rampion
Sì, causerà una perdita di memoria. Il sistema non è stato in grado di gestire il caso.
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
@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
@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