web-dev-qa-db-fra.com

Comment utiliser strdup?

J'appelle strdup et je dois allouer de l'espace pour la variable avant d'appeler strdup.

char *variable;
variable = (char*) malloc(sizeof(char*));
variable = strdup(Word);

Est-ce que je fais ça correctement? Ou y a-t-il quelque chose qui ne va pas ici?

12
Ivan Zhang

Si vous utilisez le standard POSIX strdup() , il calcule l'espace nécessaire et l'alloue et copie la chaîne source dans l'espace nouvellement alloué. Vous n'avez pas besoin de faire une malloc() vous-même; en effet, il fuit immédiatement si vous le faites puisque vous écrasez le seul pointeur vers l'espace que vous avez alloué avec le pointeur vers l'espace que strdup() a alloué.

Par conséquent:

char *variable = strdup(Word);
if (variable == 0) …process out of memory error; do not continue…
…use variable…
free(variable);

Si vous avez besoin de faire l'allocation de mémoire, alors vous devez allouer strlen(Word)+1 octets dans variable et vous pouvez alors copier Word dans cet espace nouvellement alloué.

char *variable = malloc(strlen(Word)+1);
if (variable == 0) …process out of memory error; do not continue…
strcpy(variable, Word);
…use variable…
free(variable);

Ou calculez la longueur une fois et utilisez memmove() ou peut-être memcpy():

size_t len = strlen(Word) + 1;
char *variable = malloc(len);
if (variable == 0) …process out of memory error; do not continue…
memmove(variable, Word, len);
…use variable…
free(variable);

N'oubliez pas de savoir où se trouve la free() pour chaque malloc().

21
Jonathan Leffler

vous n'avez pas besoin d'allouer d'espace pour une utilisation avec strdup, strdup le fera pour vous. Cependant, vous devez le libérer après utilisation.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main (){

    const char* s1= "Hello World";
    char* new = strdup (s1);
    assert (new != NULL);

    fprintf( stdout , "%s\n", new);

    free (new);
    return 0;
}

Edit: Soyez prudent avec C++ car le nom de la variable new convient parfaitement en C et non en C++ car c'est un nom réservé pour l'opérateur new.

9
hetepeperfan

Vous semblez confus. Oubliez ce que vous savez sur les pointeurs. Travaillons avec des ints.

int x;
x = Rand();    // Let us consider this the "old value" of x
x = getchar(); // Let us consider this the "new value" of x

Existe-t-il un moyen pour nous de récupérer l'ancienne valeur, ou a-t-elle "fui" de notre vue? En tant qu'hypothèse, supposons que vous deviez informer le système d'exploitation que vous en avez terminé avec ce nombre aléatoire, afin que le système d'exploitation effectue certaines tâches de nettoyage.

L'ancienne valeur est-elle requise pour la génération de la nouvelle valeur? Comment est-ce possible, quand getchar ne peut pas voir x?

Considérons maintenant votre code:

char *variable;
variable = (char*) malloc(sizeof(char*)); // Let us consider this the "old value" of variable
variable = strdup(Word);                  // Let us consider this the "new value" of variable

Existe-t-il un moyen pour nous de récupérer l'ancienne valeur, ou a-t-elle "fui" de notre vue? Vous êtes censé informer le système d'exploitation lorsque vous avez terminé d'utiliser la mémoire malloced, en appelant free(variable);.

L'ancienne valeur est-elle requise pour la génération de la nouvelle valeur? Comment est-ce possible, quand strdup ne peut pas voir la variable?

Pour info, voici un exemple de la façon dont strdup pourrait être implémenté:

char *strdup(const char *original) {
    char *duplicate = malloc(strlen(original) + 1);
    if (duplicate == NULL) { return NULL; }

    strcpy(duplicate, original);
    return duplicate;
}
6
autistic

Dans l'état actuel des choses, vous perdez toujours 4 à 8 octets (selon votre architecture). Indépendamment de strdup qui allouera seul la mémoire dynamique requise vous réaffectez la seule variable qui contient le pointeur vers votre zone de mémoire nouvellement malléée.

Dites simplement

char* const variable = strdup(Word);
2
bitmask