strdup () – o que faz em C?

Qual é o objective da function strdup() em C?

Exatamente o que parece, supondo que você está acostumado com a maneira abreviada em que C e UNIX atribui palavras, ele duplica strings 🙂

Tendo em mente que na verdade não faz parte do próprio padrão ISO C (a) (é uma coisa do POSIX), ele está efetivamente fazendo o mesmo que o seguinte código:

 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 } 

Em outras palavras:

  1. Ele tenta alocar memory suficiente para conter a string antiga (mais um caractere ‘\ 0’ para marcar o final da string).

  2. Se a alocação falhou, ele define errno como ENOMEM e retorna NULL imediatamente. A configuração de errno para ENOMEM é algo que o malloc faz no POSIX, portanto, não precisamos explicitamente fazê-lo em nosso strdup . Se você não é compatível com POSIX, o ISO C não determina a existência do ENOMEM então eu não incluí isso aqui (b) .

  3. Caso contrário, a alocação funcionou, então copiamos a string antiga para a nova string e retornamos o novo endereço (que o chamador é responsável por liberar em algum momento).

Tenha em mente que essa é a definição conceitual. Qualquer escritor de biblioteca que mereça seu salário pode ter fornecido um código altamente otimizado visando o processador específico que está sendo usado.


(a) Lembre-se, no entanto, que as funções que começam com str e uma letra minúscula são reservadas pela norma para futuras direções. De C11 7.1.3 Reserved identifiers :

Cada header declara ou define todos os identificadores listados em sua subcláusula associada e * opcionalmente declara ou define identificadores listados em sua subseção de direções de biblioteca futura associada. **

As direções futuras para string.h podem ser encontradas em C11 7.31.13 String handling :

Nomes de funções que começam com str , mem ou wcs e uma letra minúscula podem ser adicionados às declarações no header .


(b) A mudança seria basicamente substituída if (d == NULL) return NULL; com:

 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; } 

Talvez o código seja um pouco mais rápido do que com o strcpy() pois o caracter \0 não precisa ser pesquisado novamente (ele já estava com o strlen() ).

Não adianta repetir as outras respostas, mas observe que o strdup() pode fazer o que quiser de uma perspectiva C, já que não faz parte de nenhum padrão C. No entanto, é definido por POSIX.1-2001.

Do homem do strdup :

A function strdup() deve retornar um ponteiro para uma nova string, que é uma duplicata da string apontada por s1 . O ponteiro retornado pode ser passado para free() . Um ponteiro nulo é retornado se a nova string não puder ser criada.

Ele faz uma cópia duplicada da string passada executando um malloc e strcpy da string passada. O buffer malloc é retornado ao chamador, daí a necessidade de correr livremente no valor de retorno.

strdup () faz alocação dinâmica de memory para a matriz de caracteres, incluindo o caractere final ‘\ 0’ e retorna o endereço da memory 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 } 

Então, o que ele faz é nos dar outra string idêntica à string dada pelo seu argumento, sem precisarmos alocar memory. Mas ainda precisamos liberá-lo mais tarde.

strdup e strndup são definidos em sistemas compatíveis com POSIX como:

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

A function strdup () aloca memory suficiente para uma cópia da string str , faz a cópia e retorna um ponteiro para ela.

O ponteiro pode posteriormente ser usado como um argumento para a function free .

Se a memory insuficiente estiver disponível, NULL será retornado e errno será definido como ENOMEM .

A function strndup () copia no máximo os caracteres len da string str sempre null encerrando a string copiada.

A coisa mais valiosa que ele faz é dar a você outra string idêntica à primeira, sem precisar que você aloque memory (localização e tamanho). Mas, como observado, você ainda precisa liberá-lo (mas também não requer cálculo de quantidade).

A function strdup () é uma forma abreviada de duplicar string, recebe um parâmetro como uma constante de string ou uma string literal e aloca espaço suficiente para a string e grava os caracteres correspondentes no espaço alocado e finalmente retorna o endereço da alocação espaço para a rotina de chamada.

É simples strcpy(ptr2, ptr1) é equivalente a while(*ptr2++ = *ptr1++)

onde como: strdup é equivalente a

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

strcpy(ptr2,ptr1);

Então, se você quer que a string que você copiou seja usada em outra function (como ela é criada na seção heap), você pode usar o strdup, senão o strcpy é suficiente