Ho letto che strcpy
serve per copiare una stringa, e strdup
restituisce un puntatore a una nuova stringa per duplicare la stringa.
Potresti spiegare quali casi preferisci usare strcpy
e quali casi preferisci usare strdup
?
strcpy(ptr2, ptr1)
è equivalente a while(*ptr2++ = *ptr1++)
dove come strdup è equivalente a
ptr2 = malloc(strlen(ptr1)+1); strcpy(ptr2,ptr1);
(la versione di memcpy potrebbe essere più efficiente)
Quindi se vuoi che la stringa che hai copiato sia usata in un’altra funzione (dato che è stata creata nella sezione heap) puoi usare strdup, altrimenti è sufficiente strcpy.
Le funzioni strcpy
e strncpy
fanno parte della libreria standard C e operano sulla memoria esistente. Cioè, è necessario fornire la memoria in cui le funzioni copiano i dati di stringa e, come corollario, è necessario disporre dei propri mezzi per scoprire la quantità di memoria necessaria.
Con il strdup
, strdup
è una funzione Posix, che esegue l’allocazione dynamic della memoria per te. Restituisce un puntatore alla memoria appena allocata nella quale ha copiato la stringa. Ma ora sei responsabile di questa memoria e alla fine devi free
.
Ciò rende strdup
una delle funzioni di convenienza ” malloc
nascoste”, ed è presumibilmente anche per questo che non fa parte della libreria standard. Finché utilizzi la libreria standard, sai che devi chiamarne uno free
per ogni malloc
/ calloc
. Ma funzioni come strdup
introducono un malloc
nascosto e devi trattarlo come un malloc
per la gestione della memoria. (Un’altra funzione di allocazione nascosta è l’ abi::__cxa_demangle()
GCC. Attenzione!
strdup
alloca memoria per la nuova stringa strdup
, mentre usa strcpy
(o il suo più sicuro strncpy
varient) posso copiare una stringa in una memoria pre allocata sull’heap o sullo stack.
Nella risposta accettata , l’implementazione di strdup
è presentata come:
ptr2 = malloc(strlen(ptr1)+1); strcpy(ptr2,ptr1);
Tuttavia, questo è in qualche modo non ottimale perché sia la strlen
sia la strcpy
devono trovare la lunghezza della stringa controllando se ogni carattere è un \0
.
L’utilizzo di memcpy
dovrebbe essere più efficiente:
char *strdup(const char *src) { size_t len = strlen(src) + 1; char *s = malloc(len); if (s == NULL) return NULL; return (char *)memcpy(s, src, len); }
char *strdup(char *pszSrch)
;
strdup
alloca la memoria della dimensione della stringa originale. Se l’allocazione di memoria ha esito positivo, la stringa originale viene copiata nella stringa duplicata.
strdup
d restituisce NULL
in caso di errore. Se la memoria non è allocata, la copia fallisce con strdup
return NULL
.