2012-12-24 15 views
60

Ho letto che strcpy è per copiare una stringa e strdup restituisce un puntatore a una nuova stringa per duplicare la stringa.strcpy vs strdup

Potresti spiegare quali casi preferisci usare strcpy e quali casi preferisci usare strdup?

risposta

90

strcpy(ptr2, ptr1) è equivalente a while(*ptr2++ = *ptr1++)

dove come strdup equivale a

ptr2 = malloc(strlen(ptr1)+1); 
strcpy(ptr2,ptr1); 

(memcpy version potrebbe essere più efficiente)

Quindi, se si desidera che la stringa che è stato copiato da utilizzare in un'altra funzione (dato che è creata nella sezione heap) puoi usare strdup, altrimenti è sufficiente strcpy.

+1

Buona risposta a parte l'ultima frase, che è fonte di confusione. Immagino tu voglia dire che la durata della stringa 'strdup() può estendersi oltre la fine della funzione corrente, ma questo potrebbe comunque essere il caso (se il target di' strcpy() 'è un buffer fornito dal chiamante, variabile globale, o essa stessa allocata manualmente usando 'malloc()' o 'new'). –

+1

Sì, è vero che se il buffer fornito dal chiamante è una variabile globale o un puntatore dinamico da solo, non è necessario utilizzare strdup Ho appena indicato uno degli scenari del caso d'uso e grazie per averlo completato. –

+5

Apprezzo molto il 'while (* ptr2 ++ = * ptr1 ++)'! :) – Aloys

12

strdup alloca memoria per la nuova stringa sul mucchio, mentre usando strcpy (o il suo sicuro strncpy varient) posso copiare una stringa in una memoria pre allocata sia il cumulo o stack.

+1

Perché l'enfatico "o"? Non è possibile usare 'strcpy' per copiare in un buffer statico? –

+0

Ho tentato di sottolineare la differenza di utilizzo tra le due funzioni senza ingombrare la risposta con troppi problemi di gestione della memoria. ma sì, hai ragione sui buffer statici. – Oren

+0

Se non vuoi il disordine, puoi semplicemente terminare la risposta dopo "memoria pre-allocata" :-) –

38

Le funzioni strcpy e strncpy fanno parte della libreria standard C e funzionano sulla memoria esistente. Vale a dire, è necessario fornire la memoria in cui le funzioni copiano i dati di stringa e come corollario, è deve avere i propri mezzi di scoprire quanta memoria è necessario.

Per contrasto, strdup è una funzione Posix ed esegue automaticamente l'allocazione dinamica della memoria. Restituisce un puntatore alla memoria appena allocata nella quale ha copiato la stringa. Ma è che ora è responsabile di questa memoria e alla fine deve essere free.

Ciò rende strdup una delle "funzioni comfort" nascoste malloc "e presumibilmente anche perché non fa parte della libreria standard. Finché si utilizza la libreria standard, è necessario chiamare uno free per ogni malloc/calloc. Ma funzioni come strdup introducono un malloc nascosto e lo si deve trattare allo stesso modo di un malloc ai fini della gestione della memoria. (Un'altra funzione di allocazione nascosta è GCC abi::__cxa_demangle().) Attenzione!

0

char *strdup(char *pszSrch);

strdup allocherà 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 restituire NULL in caso di errore. Se la memoria non viene allocata, la copia fallisce strdup restituisce NULL.

6

Nel accepted answer, l'attuazione di strdup è presentato come:

ptr2 = malloc(strlen(ptr1)+1); 
strcpy(ptr2,ptr1); 

Tuttavia, che è un po sub-ottimale perché sia ​​strlen e strcpy bisogno di trovare la lunghezza della stringa controllando se ogni carattere è a \0.

Utilizzando 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); 
} 
+0

Buona risposta che separa l'uso concettuale di 'strcpy' per implementare' strdup' dalla praticità di farlo in modo efficiente. –

Problemi correlati