strdup () – cosa fa in C?

Qual è lo scopo della funzione strdup() in C?

Esattamente come suona, supponendo che tu sia abituato al modo abbreviato in cui C e UNIX assegnano le parole, duplica le stringhe ūüôā

Tenendo presente che in realtà non fa parte dello standard ISO C stesso (a) (è una cosa POSIX), sta effettivamente facendo lo stesso del seguente codice:

 char *strdup (const char *s) { char *d = malloc (strlen (s) + 1); // Space for length plus nul if (d == NULL) return NULL; // No memory strcpy (d,s); // Copy the characters return d; // Return the new string } 

In altre parole:

  1. Cerca di allocare memoria sufficiente per contenere la vecchia stringa (pi√Ļ un carattere ‘\ 0’ per contrassegnare la fine della stringa).

  2. Se l’allocazione fallisce, imposta errno su ENOMEM e restituisce immediatamente NULL . L’impostazione di errno su ENOMEM √® qualcosa di malloc in POSIX, quindi non √® necessario eseguirlo esplicitamente nel nostro strdup . Se non sei compatibile con POSIX, ISO C in realt√† non richiede l’esistenza di ENOMEM quindi non l’ho incluso qui (b) .

  3. Altrimenti l’allocazione ha funzionato, quindi copia la vecchia stringa nella nuova stringa e restituisco il nuovo indirizzo (che il chiamante √® responsabile della liberazione ad un certo punto).

Tieni presente che questa è la definizione concettuale. Qualsiasi scrittore di biblioteche che valga il proprio stipendio potrebbe aver fornito un codice fortemente ottimizzato per il particolare processore utilizzato.


(a) Tenere presente, tuttavia, che le funzioni che iniziano con str e una lettera minuscola sono riservate dallo standard per le direzioni future. Da C11 7.1.3 Reserved identifiers :

Ogni intestazione dichiara o definisce tutti gli identificativi elencati nella relativa sottoclausola associata e * facoltativamente dichiara o definisce gli identificativi elencati nella sottoclabile delle istruzioni della libreria futura associata. **

Le future direzioni per string.h possono essere trovate in C11 7.31.13 String handling :

I nomi delle funzioni che iniziano con str , mem o wcs e una lettera minuscola possono essere aggiunti alle dichiarazioni nell’intestazione .


(b) La modifica sarebbe sostanzialmente in sostituzione if (d == NULL) return NULL; con:

 if (d == NULL) { errno = ENOMEM; return NULL; } 
 char * strdup(const char * s) { size_t len = 1+strlen(s); char *p = malloc(len); return p ? memcpy(p, s, len) : NULL; } 

Forse il codice √® un po ‘pi√Ļ veloce rispetto a strcpy() dato che il carattere \0 non ha bisogno di essere perquisito di nuovo (era gi√† con strlen() ).

strdup() ripetere le altre risposte, ma tieni presente che strdup() pu√≤ fare tutto ci√≤ che vuole da una prospettiva C, poich√© non fa parte di alcuno standard C. √ą tuttavia definito dal POSIX.1-2001.

Da strdup man :

La funzione strdup() deve restituire un puntatore a una nuova stringa, che è un duplicato della stringa indicata da s1 . Il puntatore restituito può essere passato a free() . Un puntatore nullo viene restituito se non è ansible creare la nuova stringa.

Fa una copia duplicata della stringa passata eseguendo un malloc e una strcpy della stringa passata. Il buffer malloc’ed viene restituito al chiamante, da qui la necessit√† di eseguire gratuitamente il valore restituito.

strdup () esegue l’allocazione dynamic della memoria per l’array di caratteri, incluso il carattere finale ‘\ 0’ e restituisce l’indirizzo della memoria heap:

 char *strdup (const char *s) { char *p = malloc (strlen (s) + 1); // allocate memory if (p != NULL) strcpy (p,s); // copy string return p; // return the memory } 

Quindi, quello che fa √® darci un’altra stringa identica alla stringa data dal suo argomento, senza che ci imponga di allocare memoria. Ma dobbiamo ancora liberarlo, dopo.

strdup e strndup sono definiti in sistemi conformi a POSIX come:

 char *strdup(const char *str); char *strndup(const char *str, size_t len); 

La funzione strdup () alloca memoria sufficiente per una copia della stringa str , esegue la copia e restituisce un puntatore ad essa.

Il puntatore può essere successivamente utilizzato come argomento per la funzione free .

Se è disponibile memoria insufficiente, viene restituito NULL e errno è impostato su ENOMEM .

La funzione strndup () copia la maggior parte dei caratteri len dalla stringa str sempre nulla che termina la stringa copiata.

La cosa pi√Ļ preziosa che fa √® fornirti un’altra stringa identica alla prima, senza che tu debba allocare memoria (posizione e dimensioni) tu stesso. Ma, come notato, √® ancora necessario liberarlo (ma che non richiede nemmeno un calcolo della quantit√†).

La funzione strdup () √® una scorciatoia per la stringa duplicata, accetta un parametro come costante di stringa o una stringa letterale e alloca lo spazio appena sufficiente per la stringa e scrive i caratteri corrispondenti nello spazio allocato e infine restituisce l’indirizzo della stringa allocata spazio alla routine chiamante.

√ą semplice strcpy(ptr2, ptr1) √® equivalente a while(*ptr2++ = *ptr1++)

dove come: strdup è equivalente a

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

strcpy(ptr2,ptr1);

Quindi se vuoi che la stringa che hai copiato sia usata in un’altra funzione (dato che √® creata nella sezione heap) puoi usare strdup, altrimenti strcpy √® abbastanza