Quelqu'un peut-il m'expliquer pourquoi mon appel à malloc avec une taille de chaîne de 6 renvoie une taille de 4 octets? En fait, tout argument entier que je donne à malloc, j'obtiens une taille de 4. Ensuite, j'essaie de copier deux chaînes. Pourquoi ma sortie de la chaîne copiée (NULL)? Voici mon code:

int main()
{
    char * str = "string";
    char * copy = malloc(sizeof(str) + 1);
    printf("bytes allocated for copy: %d\n", sizeof(copy));
    while(*str != '\0'){
        *copy = *str;
        str++;
        copy++;
    }
    copy = '\0';
    printf("%s\n", copy);
}
10
Carlo 3 nov. 2019 à 19:47

7 réponses

sizeof(str) renvoie la taille d'un pointeur de type char*. Ce que vous devez faire est de malloc la taille de la chaîne elle-même:

char * copy = malloc(strlen(str) + 1);

En outre, ces lignes:

while(*str != '\0'){
        *copy = *str;
        str++;
        copy++;
}
copy = '\0';

Peut être réécrit facilement en C comme ceci:

while(*copy++ = *str++);
18
AraK 7 oct. 2009 à 19:01
    sizeof () vous renvoie la taille du pointeur et non la quantité d'octets alloués. Vous n'avez pas besoin de compter les octets alloués, vérifiez simplement si le pointeur renvoyé n'est pas NULL. La ligne copy = '\0'; réinitialise le pointeur et le rend NULL.
1
eyalm 7 oct. 2009 à 19:47

Vous pouvez utiliser:

size_t malloc_usable_size (void * ptr);

au lieu de: sizeof

Mais il renvoie la taille réelle du bloc de mémoire alloué! Pas la taille que vous avez passée à malloc!

-1
Informate.it 17 janv. 2014 à 11:51

Vous obtenez la taille du <<> pointeur str (4 octets), pas ce qu'il pointe?

3
Dean J 7 oct. 2009 à 19:01

Pour répondre à vos deuxièmes questions, en exécutant l'instruction copy++, vous avez modifié la valeur de copy (c'est-à-dire l'adresse en mémoire qui contient un tableau char) de sorte qu'au moment où vous imprimez-le, il pointe vers la fin du tableau plutôt que le début (la valeur retournée par malloc()). Vous aurez besoin d'une variable supplémentaire pour mettre à jour la chaîne et pour pouvoir accéder au début de la chaîne:

Modifier pour réparer le problème malloc/sizeof - merci CL.

char * str = "string";
/*   char * copy = malloc(sizeof(str) + 1);  Oops  */
char * copy = malloc(strlen(str) + 1);
char * original_copy = copy;
printf("bytes allocated for copy: %d\n", sizeof(copy));
while(*str != '\0'){
    *copy = *str;
    str++;
    copy++;
}
copy = '\0';
printf("%s\n", original_copy);
1
mob 7 oct. 2009 à 19:39

sizeof(str) renvoie l'espace nécessaire pour stocker le pointeur sur la chaîne, pas la chaîne elle-même. Vous pouvez voir la taille de la chaîne avec strlen(str) par exemple.

Ensuite, vous affectez votre pointeur copy à un entier qui a la valeur 0 (le caractère '\0'). C'est la même chose que copy = NULL, c'est ce que la fonction printf () vous montre.

2
RedGlyph 7 oct. 2009 à 19:04

sizeof () renvoie la taille du type réel de la variable. Ainsi, lorsque vous définissez votre type comme char *, il renvoie la taille d'un pointeur.

Mais si vous avez fait de votre variable un tableau, sizeof retournerait la taille du tableau lui-même, ce qui ferait ce que vous voulez faire:

char *ptr = "moo to you";
char arr[] = "moo to you";

assert(sizeof(ptr) == 4);   // assuming 32 bit
assert(sizeof(arr) == 11);  // sizeof array includes terminating NUL
assert(strlen(arr) == 10);  // strlen does not include terminating NUL
1
R Samuel Klatchko 7 oct. 2009 à 19:45