CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

malloc en C (2)

tomtex
tomtex
Niveau 8
01 mai 2009 à 10:35:50

salut,
j'ai encore une question sur le malloc :
je fais :

char *nom=(char *)malloc((11)*sizeof(char)) ;
nom="dfghnbrghrbhgrbghrbghrbkjh" ;
printf("nom : %s", nom) ;

et ça marche sans problème. mais la taille de nom ne devrait pas être limitée à 11 ?

merci

lockless
lockless
Niveau 5
01 mai 2009 à 12:35:44

Déjà ta manipulation n'est pas correcte normalement, une fois qu'on a malloc une zone, pour copier une chaine il faut utiliser strlcpy (strcpy et strncpy existe aussi, mais peuvent poser des problèmes de sécurité, cela dit je ne pense que strlcpy soit disponible partout).

Sinon, je te déconseille de caster le retour de malloc en C (cf la faq de fr.comp.lang.c, y'a plein d'arguments contre).

Sinon je saurais pas trop t'expliquer pourquoi ça marche à vrai dire.

dnob700
dnob700
Niveau 10
01 mai 2009 à 14:34:46

Il y a deux problème distinct.

Ton programme est censé fonctionné, car lorsque tu fait ton affectation (ligne 2), tu mets dans le pointeur l'adresse de cette chaine de caractère qui est déjà affecté quelque part en mémoire par le compilateur de manière statique. Le problème vient ici de ce que tu as une fuite de mémoire car après l'affectation le pointeur ne pointe plus vers la même zone de mémoire (tu peut le vérifier avec un printf("%p\n",nom)).

Mais c'est une opération qui est valable, sauf que tu ne doit donc pas allouer le pointeur avant de lui affecter un valeur.

Par contre, même si tu utilisais strcpy (strcpy(nom,"...")) ton programme pourrait fonctionner, car la fonction strcpy ne va pas vérifier si tu dépasse la taille du tampon que tu lui donne. De même pour le printf. Mais le problème est que tu risque d'écraser des données qui sont situées après l'espace alloué pour ta variables nom.

Cela dit, il y a certain compilo qui vont générer du code pour te prévenir quand ça c'est produit, cela dit, ce n'est pas une raison.

Tu peut aussi utiliser la fonction strncpy plutôt que strcpy pour la copie, à qui tu donne la taille du buffer pour être sûr qu'il n'y ait pas de dépasssement de mémoire. Normalement, il ne faudrait jamais utiliser strcpy, mais toujours strncpy.

chris_27
chris_27
Niveau 10
01 mai 2009 à 18:57:22

Au passage :

char *nom=(char *)malloc((11)*sizeof(char)) ;

:d) je pense que ce que tu voulais faire se fait via :
char nom[11];

tomtex
tomtex
Niveau 8
01 mai 2009 à 19:06:07

ok merci je pense avoir compris ; Chris_27, mon but ici était d'utiliser malloc pour comprendre :ok:

Paulop
Paulop
Niveau 12
01 mai 2009 à 23:36:32

Certes mais cela revient au même dans le cas présent ^^

chris_27
chris_27
Niveau 10
02 mai 2009 à 02:22:32

tomtex : dans ce cas, il faut se mettre dans une situation où tu as vraiment besoin de malloc. Par exemple, faire un code qui calcule la somme de n nombres (où n et les n nombres sont entrés par l'utilisateur à l'éxecution) par exemple.

dnob700
dnob700
Niveau 10
02 mai 2009 à 11:21:38

Ça ne revient pas vraiment au même car avec la solution char nom[11], on n'a pas le droit de faire « nom = "..."; » mais seulement d'utiliser strcpy ce qui n'est pas forcément le but.

chris_27
chris_27
Niveau 10
02 mai 2009 à 13:21:56

dnob700 : c'est ce que je pensais aussi, mais c'est pas moral… testons :

chris@tarsonis:~/Temp% cat > toto.c << EOF
heredoc> int main(void) {
heredoc> char *tmp;
heredoc> tmp = "puic";
heredoc> return 0;
heredoc> }
heredoc> EOF
chris@tarsonis:~/Temp% gcc toto.c
chris@tarsonis:~/Temp% sed -i 's|\*tmp|tmp\[10\]|' toto.c
chris@tarsonis:~/Temp% gcc toto.c
toto.c: In function ‘main’:
toto.c:3: error: incompatible types in assignment

Si tu sais pourquoi « char tmp[10] = "puic"; » est valide et « char tmp[10]; tmp = "puic"; » non, je veux bien une explication.

Enfin bon, justement, il aurait mieux vallu pour tomtex faire une déclaration de "type tableau". Au moins, il aurait été prévenu de son erreur. :-)

Paulop
Paulop
Niveau 12
02 mai 2009 à 15:34:35

C'est normal qu'il y ait une erreur Chris, dans le premier cas tu crée pointeur qui pointe sur l'adresse mémoire crée statiquement pour loger "puic".
Dans le second cas tu crée un tableau statique de 10 caractères, tu dois donc le remplir caractère par caractère, ou bien avec strcpy.

Un code qui pourra ptet t'aider :

  1. include <stdio.h>
  2. include <string.h>
  3. include <stdlib.h>

int main(void){
char tmp[10];
char* foo = (char*) malloc(5 * sizeof(char));

printf("Ladresse que pointe foo est :\n");
printf("%p\n",foo);

  • (foo) = 'p';
  • (foo+1) = 'u';

foo[2] = 'i';
foo[3] = 'c';

printf("Ladresse que pointe foo est :\n");
printf("%p\n",foo);

strcpy(foo,"puic");

printf("Ladresse que pointe foo est :\n");
printf("%p\n",foo);

foo="dfghnbrghrbhgrbghrbghrbkjh";

printf("Ladresse que pointe foo est:\n");
printf("%p\n",foo);

//On va donner une valeur a tmp...
strcpy(tmp,"puic");

printf("Voici ce que valent tmp et foo :\n");

printf("%s\n",tmp);
printf("%s\n",foo);

printf("Si maintenant je tente un strcpy sur foo...\n");
strcpy(foo,"Aïe");
}

En voici la sortie :

Schmac:Dev Paul$ ./a.out
Ladresse que pointe foo est :
0x100120
Ladresse que pointe foo est :
0x100120
Ladresse que pointe foo est :
0x100120
Ladresse que pointe foo est:
0x1f76
Voici ce que valent tmp et foo :
puic
dfghnbrghrbhgrbghrbghrbkjh
Si maintenant je tente un strcpy sur foo...
Bus error

dnob700
dnob700
Niveau 10
02 mai 2009 à 21:31:27

contrairement à ce qui se passe dans le cas d'une déclaration de fonction, un char nom[10] n'est pas un char* mais un espace en mémoire, donc les valeurs que tu peut lui donner sont des caractères dans ces différentes case, mais pas un char*.

L'autre manière de voir ça est que lorsque tu déclare un char nom[10] tu alloue statiquement de la mémoire pour ta chaine, et le compilateur ne peut pas te permettre de la perdre comme tu le fait quand tu efface une mémoire renvoyer par malloc (là il ne peut rien faire pour t'en empêcher).

Par exemple si tu déclare char nom[10], tu peut passer nom à une fonction qui attend un char* car c'est sans danger (ça pointe vers la bonne zone en mémoire), mais tu ne peut pas passer &nom à une fonction qui attend un char** car là tu pourrais modifier la destination tandis que nom doit toujours pointer vers la zone qui a été alloué statiquement par le compilateur.

chris_27
chris_27
Niveau 10
03 mai 2009 à 12:16:14

Ok, c'est l'aspect *statique* qui m'avait échappé. :rouge:

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Création de sites web
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment