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
Bonjour.

Je suis débutant en C et j'apprend à utiliser les pointeurs.
J'ai écris un code censé convertir un nombre de minutes en heures et minutes, je le compile sans erreur mais quand je le lance, j'entre un nombre grâce à scanf mais quand j'appuie sur entrée windows me dit que le programme a cessé de fonctionner.
Voici le code :


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

void convert(unsigned char minutesDepart, unsigned char* heures, unsigned char* minutes)
{
*heures = minutesDepart / 60;
*minutes = minutesDepart % 60;
}

int main(int argc, char *argv[])
{
printf("\nEntrez le nombre de minutes :\t");
unsigned char minutes = 0, heures = 0, minutesDepart;
scanf("%d", minutesDepart);
convert(minutesDepart, &heures, &minutes);
printf("\n\n%d minutes = %d heures et %d minutes\n\n", minutesDepart, heures, minutes);
system("PAUSE");
return 0;
}



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
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,
1
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
Ç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 ?
0
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
Salut,
unsigned char minutes = 0, heures = 0;
int minutesDepart;
scanf("%d",&minutesDepart); (sinon error de segmentation je pense...
@+
0
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
@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.
0

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
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...
@+
0
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
Ça ne me choque pas qu'on assigne 0 à un char, c'est pas vraiment le propos. :)
0
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
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....
@+
0
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
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 ?
0
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
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!!
0
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
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.
0
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
Merci beaucoup fiddy j'ai du faire une faute de frappe en tapant le scanf et je ne m'en était pas aperçu.
0
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
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.
0
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
@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!!;))
@+
0
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
@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).
0
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
@fiddy
Merci pour la precision..
Je t'avouerai que je n'utilise jamais scanf...donc quelques lacunes sur cette fonction!!;)
@+
0