Problème C avec des pointeurs
Résolu/Fermé
MaxiLink
Messages postés
63
Date d'inscription
mardi 10 mars 2009
Statut
Membre
Dernière intervention
19 juin 2011
-
9 mai 2010 à 14:38
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 - 9 mai 2010 à 20:00
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 - 9 mai 2010 à 20:00
15 réponses
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
9 mai 2010 à 15:35
9 mai 2010 à 15:35
Bonjour,
unsigned char minutes = 0, heures = 0, minutesDepart;
scanf("%d", minutesDepart);
minutesDepart est de type unsigned char. Du coup, deux problèmes.
Le premier est qu'il faut mettre l'adresse mémoire et non la variable elle-même. Sinon le compilateur va chercher à accéder à une case mémoire non maitrisée. Donc très probable segfault.
Le deuxième problème est que la variable est codée sur sizeof(int) byte, soit 4 bytes au minimum alors que unsigned char est codé sur 1 byte. Ceci va donc modifier les cases de ta pile. C'est ce qu'on appelle un buffer overflow.
Je te conseille donc d'abandonner tes unsigned char et de passer par un simple integer. Et de bien penser à mettre l'adresse mémoire (avec l'esperluette &) dans le scanf. D'autant plus que dans ton cas (unsigned char), tu limites tes valeurs à 255 dans la plupart des cas.
Cdlt,
unsigned char minutes = 0, heures = 0, minutesDepart;
scanf("%d", minutesDepart);
minutesDepart est de type unsigned char. Du coup, deux problèmes.
Le premier est qu'il faut mettre l'adresse mémoire et non la variable elle-même. Sinon le compilateur va chercher à accéder à une case mémoire non maitrisée. Donc très probable segfault.
Le deuxième problème est que la variable est codée sur sizeof(int) byte, soit 4 bytes au minimum alors que unsigned char est codé sur 1 byte. Ceci va donc modifier les cases de ta pile. C'est ce qu'on appelle un buffer overflow.
Je te conseille donc d'abandonner tes unsigned char et de passer par un simple integer. Et de bien penser à mettre l'adresse mémoire (avec l'esperluette &) dans le scanf. D'autant plus que dans ton cas (unsigned char), tu limites tes valeurs à 255 dans la plupart des cas.
Cdlt,
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
Modifié par EminoMeneko le 9/05/2010 à 14:43
Modifié par EminoMeneko le 9/05/2010 à 14:43
Ça fait un moment que j'ai pas fait de C mais en commençant par lire le prototype de ta fonction convert() je vois déjà un gros problème.
Où est le transtypage ?
Autre chose. Comment tu fais pour exploiter le traitement de la fonction convert ?
Où est le transtypage ?
Autre chose. Comment tu fais pour exploiter le traitement de la fonction convert ?
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
Modifié par chuka le 9/05/2010 à 14:49
Modifié par chuka le 9/05/2010 à 14:49
Salut,
unsigned char minutes = 0, heures = 0;
int minutesDepart;
scanf("%d",&minutesDepart); (sinon error de segmentation je pense...
@+
unsigned char minutes = 0, heures = 0;
int minutesDepart;
scanf("%d",&minutesDepart); (sinon error de segmentation je pense...
@+
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
Modifié par EminoMeneko le 9/05/2010 à 14:55
Modifié par EminoMeneko le 9/05/2010 à 14:55
@Chuka tu sais ce que ça signifie en C/C++ d'assigner la valeur 0 à un char ? C'est encore pire que ce qu'il avait fait. Lui avait envoyé un pointeur sur char et de mémoire c'est ce qu'on fait quand on veut accéder à une chaine de caractères... Je viens de donner un indice sur la raison pour laquelle j'ai parlé de transtypage.
PS: Au lieu de faire System("PAUSE"); nous on utilisait un simple getch(); pour éviter que la fenêtre ne se ferme. Après tu fais comme tu veux. Je dis ça pour info.
PS: Au lieu de faire System("PAUSE"); nous on utilisait un simple getch(); pour éviter que la fenêtre ne se ferme. Après tu fais comme tu veux. Je dis ça pour info.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
Modifié par chuka le 9/05/2010 à 15:04
Modifié par chuka le 9/05/2010 à 15:04
Salut,
tous les jours j'assigne des uchar avec comme init valeur 0...ca me permet de gagné 3 octets en memoire au lieu de 4 pour un int....sur des valeur allant de 0 à 0xFF...je vois pas ce qu'il y a de choquant...
@+
tous les jours j'assigne des uchar avec comme init valeur 0...ca me permet de gagné 3 octets en memoire au lieu de 4 pour un int....sur des valeur allant de 0 à 0xFF...je vois pas ce qu'il y a de choquant...
@+
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
9 mai 2010 à 15:04
9 mai 2010 à 15:04
Ça ne me choque pas qu'on assigne 0 à un char, c'est pas vraiment le propos. :)
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
Modifié par chuka le 9/05/2010 à 15:18
Modifié par chuka le 9/05/2010 à 15:18
Dans ca fonction:
void convert(unsigned char minutesDepart, unsigned char* heures, unsigned char* minutes)
il passe comme argument un pointeur sur un uchar...peu importe que ce soit une chaine ou pas...la valeur du pointeur sera celle passé en argument...pas besoin de transtypage....(car en plus heures et minutes sont de type uchar...)
le probleme vient de son scanf qui lui a besoin d'une adresse memoire pour mettre la valeur recuperée au clavier...or il a mis la valeur....donc plantage....
@+
void convert(unsigned char minutesDepart, unsigned char* heures, unsigned char* minutes)
il passe comme argument un pointeur sur un uchar...peu importe que ce soit une chaine ou pas...la valeur du pointeur sera celle passé en argument...pas besoin de transtypage....(car en plus heures et minutes sont de type uchar...)
le probleme vient de son scanf qui lui a besoin d'une adresse memoire pour mettre la valeur recuperée au clavier...or il a mis la valeur....donc plantage....
@+
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
9 mai 2010 à 15:20
9 mai 2010 à 15:20
Rappel moi la plage de nombre qu'il peut exploiter avec ça. Je ne me souviens plus c'est assez vieux pour moi le C.
Par contre je me vois mal travailler sur des nombre avec des types autres que ce qui est prévu pour des nombres quand bien même c'est exploitable avec un char. Un short ça n'irait pas ?
Par contre je me vois mal travailler sur des nombre avec des types autres que ce qui est prévu pour des nombres quand bien même c'est exploitable avec un char. Un short ça n'irait pas ?
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
9 mai 2010 à 15:23
9 mai 2010 à 15:23
uchar de 0 à 0xFF
ushort de 0 à 0xFFFF
Je t'avoue un ushort serait plus approprié (pour minutesDepart) mais pour heures et minutes un uchar sufffit amplement!!
ushort de 0 à 0xFFFF
Je t'avoue un ushort serait plus approprié (pour minutesDepart) mais pour heures et minutes un uchar sufffit amplement!!
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
9 mai 2010 à 15:38
9 mai 2010 à 15:38
uchar 0xFF => 256 c'est ça ? avec le 0, 255. Et si je veut convertir 260 minutes ?
Pour heures et minutes je veux bien mais pour minutesDepart avec un uchar on ira pas loin.
Et puis à l'heure où la tendance à dépasser les 4Go sur les machine se met en marche choisir son type de donnée comme un pingre ça me fait légèrement sourire.
Après c'est juste un code pour exemple OK mais pourquoi ne pas utiliser un type pour les nombres quand on travail avec des nombres ?
Tu va gagner deux octets ? Et alors ?
Après je dis ça, je dis rien. Chacun fera selon son bon vouloir. Moi je m'en tiens à la logique et à l'expérience de personnes qui ont des dixaines d'années de prog dans les pattes à savoir les professionnels reconnus dont j'ai lu les bouquins et mes profs d'infos. Ça me parait beaucoup plus logique perso.
Pour heures et minutes je veux bien mais pour minutesDepart avec un uchar on ira pas loin.
Et puis à l'heure où la tendance à dépasser les 4Go sur les machine se met en marche choisir son type de donnée comme un pingre ça me fait légèrement sourire.
Après c'est juste un code pour exemple OK mais pourquoi ne pas utiliser un type pour les nombres quand on travail avec des nombres ?
Tu va gagner deux octets ? Et alors ?
Après je dis ça, je dis rien. Chacun fera selon son bon vouloir. Moi je m'en tiens à la logique et à l'expérience de personnes qui ont des dixaines d'années de prog dans les pattes à savoir les professionnels reconnus dont j'ai lu les bouquins et mes profs d'infos. Ça me parait beaucoup plus logique perso.
MaxiLink
Messages postés
63
Date d'inscription
mardi 10 mars 2009
Statut
Membre
Dernière intervention
19 juin 2011
9 mai 2010 à 15:50
9 mai 2010 à 15:50
Merci beaucoup fiddy j'ai du faire une faute de frappe en tapant le scanf et je ne m'en était pas aperçu.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
Modifié par fiddy le 9/05/2010 à 15:56
Modifié par fiddy le 9/05/2010 à 15:56
Que ce soit uchar ou int, ou même long, il y aura le même problème, à savoir la limite imposée par le nombre de bytes. Avec long au lieu de uchar, on repousse juste le problème.
C'est pourquoi, la seule vraie solution est de vérifier qu'il n'y a pas eu d'integer overflow.
C'est pourquoi, la seule vraie solution est de vérifier qu'il n'y a pas eu d'integer overflow.
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
Modifié par chuka le 9/05/2010 à 16:10
Modifié par chuka le 9/05/2010 à 16:10
@EminoMeneko
Je suis d'accord avec toi....sur une appli comme cela, passer par des int seraient plus simple...
Néanmoins, je bosse dans l'embarqué et un octet et un octet!!
Le temps d'execution d'une fonction suivant le µp ou µc peut passer du de 10 micro à 50 micro...suivant l'utilisation de ushort ou de type 32bits....donc je te l'accorde, ici cela n'a pas de sens, mais dans bon nombre de cas, cela en a un!!;)
Apres dans les solutions proposés, j'essaie de garder au max le code qui nous est proposé....bon à l'intervenant de le modifier suivant ses envies et suivant l'appli qu'il doit faire....(à priori je ne sais pas pourquoi ce code est fait!!;))
@+
Je suis d'accord avec toi....sur une appli comme cela, passer par des int seraient plus simple...
Néanmoins, je bosse dans l'embarqué et un octet et un octet!!
Le temps d'execution d'une fonction suivant le µp ou µc peut passer du de 10 micro à 50 micro...suivant l'utilisation de ushort ou de type 32bits....donc je te l'accorde, ici cela n'a pas de sens, mais dans bon nombre de cas, cela en a un!!;)
Apres dans les solutions proposés, j'essaie de garder au max le code qui nous est proposé....bon à l'intervenant de le modifier suivant ses envies et suivant l'appli qu'il doit faire....(à priori je ne sais pas pourquoi ce code est fait!!;))
@+
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 842
9 mai 2010 à 16:14
9 mai 2010 à 16:14
@chuka
Néanmoins, je bosse dans l'embarqué et un octet et un octet!!
Si tu utilises : scanf("%d",...), tu ne peux pas mettre derrière un uchar. Sinon va récrire dans le stack.
Si tu veux mettre une petite valeur, tu vas devoir passer par un short (le flag sera donc %h).
Néanmoins, je bosse dans l'embarqué et un octet et un octet!!
Si tu utilises : scanf("%d",...), tu ne peux pas mettre derrière un uchar. Sinon va récrire dans le stack.
Si tu veux mettre une petite valeur, tu vas devoir passer par un short (le flag sera donc %h).
chuka
Messages postés
965
Date d'inscription
samedi 11 octobre 2008
Statut
Membre
Dernière intervention
29 juillet 2010
378
9 mai 2010 à 20:00
9 mai 2010 à 20:00
@fiddy
Merci pour la precision..
Je t'avouerai que je n'utilise jamais scanf...donc quelques lacunes sur cette fonction!!;)
@+
Merci pour la precision..
Je t'avouerai que je n'utilise jamais scanf...donc quelques lacunes sur cette fonction!!;)
@+