IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Verifier la valeur d'un unsigned long int


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut Verifier la valeur d'un unsigned long int
    Bonjour,

    Voila j'ai un probleme en ce qui concerne l'utilisation des unsigned.
    J'ai une fonction qui a pour prototype :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void         *ma_fonction(unsigned long int taille);
    Je ne peux malhereusement pas toucher a ce prototype. Lorsque j'envoi un nombre superieur a 0 a ma_fonction, aucun soucis (normal !). Mais je voudrais que lorsque j'envoi a cette meme fonction un nombre negatif, elle me mette une erreur. Or, je ne sais pas comment checker la valeur de la variable "taille" puisque lorsque j'envoi a ma_fonction par exemple "-20", elle le transforme en :

    4294967295 - 20 = 4294967275

    La taille fait donc comme qui dirait "le tour en sens inverse".
    Comment remedier a ce probleme sachant que je ne peux pas checker "taille" en amont dans la fonction qui appelle "ma_fonction"?

    Merci

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Si tu utilises gcc comme compilateur, tu peux utiliser l'option -Wconversion pour capturer l'erreur sous forme d'avertissement à la compilation. Sinon, si ta fonction ne travaille pas avec les entiers supérieurs à LONG_MAX, toutes les valeurs de taille telles que LONG_MAX < taille <= ULONG_MAX sont en principe des entiers négatifs ayant été convertis. Dans ce cas, il te suffit de renvoyer une erreur lorsque taille est supérieure à LONG_MAX.

    Sinon, je n'ai pas d'autre idée.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Johor Voir le message
    je voudrais que lorsque j'envoi a cette meme fonction un nombre negatif, elle me mette une erreur.
    Ca n'a pas de sens. Pour ma_fonction(), taille a forcement une valeur positive puisque c'est un unsigned long.

    Comment remedier a ce probleme sachant que je ne peux pas checker "taille" en amont dans la fonction qui appelle "ma_fonction"?
    Pourquoi pas ? Il est evident que c'est au moment de la conversion long vers unsigned long qu'il faut tester que ta valeur n'est pas negative. Si tu travailles avec des contraintes impossibles du genre "je ne peux pas tester avant l'appel a la fonction", alors ton probleme n'a pas de solution.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Ca n'a pas de sens. Pour ma_fonction(), taille a forcement une valeur positive puisque c'est un unsigned long.
    Pour etre clair, voici a quoi ressemble mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void           *ma_fonction(unsigned long int taille)
    {
        bla bla bla;
    }
     
    int             main()
    {
        ma_fonction(-20);
    }
    Citation Envoyé par DaZumba Voir le message
    Pourquoi pas ? Il est evident que c'est au moment de la conversion long vers unsigned long qu'il faut tester que ta valeur n'est pas negative. Si tu travailles avec des contraintes impossibles du genre "je ne peux pas tester avant l'appel a la fonction", alors ton probleme n'a pas de solution.
    En fait il s'agit de la fonction malloc que je refais, donc bien evidement je la teste en refaisant une lib et je renomme "ma_fonction" en "malloc". Donc c'est bien dans cette fonction que la valeur doit etre checkee, et pas en amont.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Pour moi, c'est bien en amont que ça doit être vérifié: Car si on essaie de passer une valeur négative à malloc(), ce sera tout aussi faux que si on essaie de la passer à ta fonction...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Johor Voir le message
    Donc c'est bien dans cette fonction que la valeur doit etre checkee, et pas en amont.
    A l'interieur de ta fonction, tu as un unsigned long. Par definition, ce ne peut pas etre un nombre negatif. Tu pourrais essayer de "deviner" que ton unsigned long provient de la conversion d'un long negatif, comme le propose Thierry Chappuis, mais si l'utilisateur veut allouer une tres grande taille, tu risques de lui interdire sous pretexte que c'est "peut-etre" une taille negative convertie. Fais comme malloc() -- si tu demandes malloc((size_t) -1) il va tenter d'allouer un gros bloc. La seule taille speciale pour malloc() est zero, ou le comportement est defini par l'implementation.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Ouai en gros j'ai pas vraiment de solution possible. Moi je pensais utiliser une fonction X ou Y qui irait checker dans la memoire pour voir si la taille specifiee n'a pas ete convertie. Mais ca doit pas exister...

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Johor Voir le message
    Ouai en gros j'ai pas vraiment de solution possible. Moi je pensais utiliser une fonction X ou Y qui irait checker dans la memoire pour voir si la taille specifiee n'a pas ete convertie. Mais ca doit pas exister...
    Non, ça n'existe pas. Et je ne vois pas comment elle procéderait. Le contenu de la mémoire n'est pas typé. Une telle fonction ne verrait rien d'autre qu'une suite interminable de 0 et de 1. C'est l'interprétation par le programme des données en mémoire qui fait apparaître la notion de type.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Tout a fait d'accord pour la memoire non typee, donc bon, aucune solution a l'horizon.
    Merci a ceux qui m'ont repondu, et malgres tout je demanderais a des eleves d'annees precedentes dans mon ecole pour savoir comment ils ont fait pour remedier a ce probleme, et je posterais l'astuce ici pour ceux que ca interresse.

    A bientot !

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Johor Voir le message
    Tout a fait d'accord pour la memoire non typee, donc bon, aucune solution a l'horizon.
    Merci a ceux qui m'ont repondu, et malgres tout je demanderais a des eleves d'annees precedentes dans mon ecole pour savoir comment ils ont fait pour remedier a ce probleme, et je posterais l'astuce ici pour ceux que ca interresse.

    A bientot !
    Quelle astuce cherches-tu? Si j'ai bien compris ton problème, tu réimplanter malloc(). malloc() ne fait pas la vérification que tu demandes et, comme l'a déjà dit DaZumba, malloc((size_t) -1) va tenter d'allouer un espace mémoire de grande taille. Dès lors, il n'y a pas d'astuce à trouver.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 962
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 962
    Par défaut
    Gio,

    Il y a bien une solution, et elle est triviale : il suffit que tu saches ce que tu fais.

  12. #12
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par droggo Voir le message
    Gio,

    Il y a bien une solution, et elle est triviale : il suffit que tu saches ce que tu fais.
    Lorsqu'on programme une fonction de bibliothèque, c'est parfois le code client qui pose problème

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Quelle astuce cherches-tu? Si j'ai bien compris ton problème, tu réimplanter malloc(). malloc() ne fait pas la vérification que tu demandes et, comme l'a déjà dit DaZumba, malloc((size_t) -1) va tenter d'allouer un espace mémoire de grande taille. Dès lors, il n'y a pas d'astuce à trouver.
    M'en fous, je recode le noyau !

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Johor Voir le message
    Voila j'ai un probleme en ce qui concerne l'utilisation des unsigned.
    Bingo! Le problème est lié à l'utilisation d'entiers non-signés. Conclusion...

    Citation Envoyé par Johor Voir le message
    J'ai une fonction qui a pour prototype :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void         *ma_fonction(unsigned long int taille);
    Je ne peux malhereusement pas toucher a ce prototype.
    Alors tu es coincé.

    Citation Envoyé par Johor Voir le message
    Lorsque j'envoi un nombre superieur a 0 a ma_fonction, aucun soucis (normal !). Mais je voudrais que lorsque j'envoi a cette meme fonction un nombre negatif, elle me mette une erreur. Or, je ne sais pas comment checker la valeur de la variable "taille" puisque lorsque j'envoi a ma_fonction par exemple "-20", elle le transforme en :

    4294967295 - 20 = 4294967275

    La taille fait donc comme qui dirait "le tour en sens inverse".
    Comment remedier a ce probleme sachant que je ne peux pas checker "taille" en amont dans la fonction qui appelle "ma_fonction"?
    La réponse est dans la question : on ne peut pas. Donc, il faut éviter de ce retrouver dans une telle situation.

    La leçon est : un argument qui est positif ne doit pas être déclarer comme non-signé.

    Citation Envoyé par Johor Voir le message
    En fait il s'agit de la fonction malloc que je refais, donc bien evidement je la teste en refaisant une lib et je renomme "ma_fonction" en "malloc".
    Tu reimplémentes une libc?

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Citation Envoyé par corrector Voir le message
    Tu reimplémentes une libc?
    Oui exact, je reimplemente la lib C avec les fonctions malloc, realloc et free. Mes fonctions marchent bien puisque je lance des programmes avec et ils ne plantent pas (genre gimp, firefox, mozilla et tout le touti). Donc par consequent, a priori si ces programmes sont bien codes, ca ne pose pas de probleme puisque les programmeurs sont pas assez bete pour faire des mallocs negatifs. Mais cette possibilite va etre verifiee pour mon rendu. Si comme certains disent ici que la taille est checkee en amont, pourquoi alors un appel a malloc avec un nombre negatif renvoie un pointeur null ?!

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Parce que ce nombre négatif est considéré comme un nombre positif énorme, trop grand pour que malloc() puisse réserver une plage mémoire continue d'une telle taille.

    Sous un Windows 32 bits, une taille négative passée à malloc() correspond à une taille supérieure à 2Go, alors que la mémoire "utilisateur" d'un processus est justement limitée à 2Go.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $>cat main.c
    int     main()
    {
      char  *test;
     
      test = malloc(-1);
      printf("%s\n", test);
      return (0);
    }
     
    $>cc main.c -o test
    $>./test
    (null)
    ainsi que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    $>cat main.c
    int     main()
    {
     
      char  *test;
     
      test = malloc(-1);
      test[0] = 'a';
      test[1] = 0;
      printf("%s\n", test);
      return (0);
    }
    $>cc main.c -o test
    $>./test
    Segmentation fault
    (je precise que je suis sous freebsd)

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    J'ai répondu à la question.
    malloc(-1) correspond, sur un système 32 bits, à malloc(4294967295), ce qui revient à demander une taille de 4Go moins un octet.
    ...Et sur aucun système 32bits il n'est possible d'allouer une telle quantité de mémoire contigüe à un programme, avec un simple malloc().

    ---> Donc, malloc() échoue et retourne NULL.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 28
    Par défaut
    donc un malloc de -4294967275 devrait correspondre en realite a un malloc de 20 ?

  20. #20
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Non, car il est impossible de coder -4294967275 sur un entier 32 bits, qu'il soit signé ou non.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 11
    Dernier message: 18/03/2011, 16h10
  2. convertir une valeur stocké sur 4 unsigned long en décimal
    Par juanito003 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/12/2007, 20h57
  3. Réponses: 1
    Dernier message: 17/10/2007, 14h01
  4. unsigned long long int
    Par salseropom dans le forum C
    Réponses: 10
    Dernier message: 21/12/2006, 22h43
  5. petit probleme avec un (unsigned long int)
    Par Micks71 dans le forum C
    Réponses: 6
    Dernier message: 19/05/2006, 12h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo