[Langage C] Overflow, limite ?

Fermé
jonathan - 24 nov. 2008 à 23:52
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 26 juil. 2012 à 00:22
Bonjour,

Je vous explique rapidement ma situation, je suis en échange Erasmus à Madrid en Espagne, j'ai un petit travail à faire, mais je dois dire que j'ai pas tout compris les cours à cause de la langue.

Donc si quelqu'un qui s'y connait un peu en C pourrait m'expliquer, me donner quelques sur ce quoi je devrais travailler ca serait vrmt sympa.

Voici le sujet (il est en anglais d'origine) :
Write a simple C program to show the limits of base data types using the information available in . Report, at least, limits of int, short, float and double. Report also the effects of going beyond limits (i.e. the effect of overflows).

Merci bcp d'avance :)

Jonathan
A voir également:

7 réponses

kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
25 nov. 2008 à 00:26
A propos dans limits.h tu as les limites de chaque types.
Je le colle ici parce que ça m'amuse:

/* Copyright (C) 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2005
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/*
 *	ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types	<limits.h>
 */

#ifndef _LIBC_LIMITS_H_
#define _LIBC_LIMITS_H_	1

#include <features.h>


/* Maximum length of any multibyte character in any locale.
   We define this value here since the gcc header does not define
   the correct value.  */
#define MB_LEN_MAX	16


/* If we are not using GNU CC we have to define all the symbols ourself.
   Otherwise use gcc's definitions (see below).  */
#if !defined __GNUC__ || __GNUC__ < 2

/* We only protect from multiple inclusion here, because all the other
   #include's protect themselves, and in GCC 2 we may #include_next through
   multiple copies of this file before we get to GCC's.  */
# ifndef _LIMITS_H
#  define _LIMITS_H	1

#include <bits/wordsize.h>

/* We don't have #include_next.
   Define ANSI <limits.h> for standard 32-bit words.  */

/* These assume 8-bit `char's, 16-bit `short int's,
   and 32-bit `int's and `long int's.  */

/* Number of bits in a `char'.	*/
#  define CHAR_BIT	8

/* Minimum and maximum values a `signed char' can hold.  */
#  define SCHAR_MIN	(-128)
#  define SCHAR_MAX	127

/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#  define UCHAR_MAX	255

/* Minimum and maximum values a `char' can hold.  */
#  ifdef __CHAR_UNSIGNED__
#   define CHAR_MIN	0
#   define CHAR_MAX	UCHAR_MAX
#  else
#   define CHAR_MIN	SCHAR_MIN
#   define CHAR_MAX	SCHAR_MAX
#  endif

/* Minimum and maximum values a `signed short int' can hold.  */
#  define SHRT_MIN	(-32768)
#  define SHRT_MAX	32767

/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
#  define USHRT_MAX	65535

/* Minimum and maximum values a `signed int' can hold.  */
#  define INT_MIN	(-INT_MAX - 1)
#  define INT_MAX	2147483647

/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
#  define UINT_MAX	4294967295U

/* Minimum and maximum values a `signed long int' can hold.  */
#  if __WORDSIZE == 64
#   define LONG_MAX	9223372036854775807L
#  else
#   define LONG_MAX	2147483647L
#  endif
#  define LONG_MIN	(-LONG_MAX - 1L)

/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
#  if __WORDSIZE == 64
#   define ULONG_MAX	18446744073709551615UL
#  else
#   define ULONG_MAX	4294967295UL
#  endif

#  ifdef __USE_ISOC99

/* Minimum and maximum values a `signed long long int' can hold.  */
#   define LLONG_MAX	9223372036854775807LL
#   define LLONG_MIN	(-LLONG_MAX - 1LL)

/* Maximum value an `unsigned long long int' can hold.  (Minimum is 0.)  */
#   define ULLONG_MAX	18446744073709551615ULL

#  endif /* ISO C99 */

# endif	/* limits.h  */
#endif	/* GCC 2.  */

#endif	/* !_LIBC_LIMITS_H_ */

 /* Get the compiler's limits.h, which defines almost all the ISO constants.

    We put this #include_next outside the double inclusion check because
    it should be possible to include this file more than once and still get
    the definitions from gcc's header.  */
#if defined __GNUC__ && !defined _GCC_LIMITS_H_
/* `_GCC_LIMITS_H_' is what GCC's file defines.  */
# include_next <limits.h>
#endif

/* The <limits.h> files in some gcc versions don't define LLONG_MIN,
   LLONG_MAX, and ULLONG_MAX.  Instead only the values gcc defined for
   ages are available.  */
#if defined __USE_ISOC99 && defined __GNUC__
# ifndef LLONG_MIN
#  define LLONG_MIN	(-LLONG_MAX-1)
# endif
# ifndef LLONG_MAX
#  define LLONG_MAX	__LONG_LONG_MAX__
# endif
# ifndef ULLONG_MAX
#  define ULLONG_MAX	(LLONG_MAX * 2ULL + 1)
# endif
#endif

#ifdef	__USE_POSIX
/* POSIX adds things to <limits.h>.  */
# include <bits/posix1_lim.h>
#endif

#ifdef	__USE_POSIX2
# include <bits/posix2_lim.h>
#endif

#ifdef	__USE_XOPEN
# include <bits/xopen_lim.h>
#endif
2
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11
25 nov. 2008 à 00:27
Oui mais il veut démontré comment on sait que c'est les valeurs maximal...
1
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
25 nov. 2008 à 00:36
Oui mais il veut démontré comment on sait que c'est les valeurs maximal..
Non.
Il dit : Write a simple C program to show the limits of base data types
Ca ne veut pas dire qu'on calcule la limite mais qu'on mette en évidence la limite par un programme.
0
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
25 nov. 2008 à 00:42
Oui mais comme je l'ai dit ce n'est pas très intéressant d'utiliser une bibli' standard.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844 > Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009
25 nov. 2008 à 00:45
Oui mais comme je l'ai dit ce n'est pas très intéressant d'utiliser une bibli' standard.
On ne parle pas d'utiliser une bibli standard. Mais de faire un code qui montre qu'il y a une limite.
Du genre : for(char a=0; a>=0;a++); Normalement, cela doit conduire à une boucle infinie. Et pourtant, cela s'arrête, car la valeur est passée négative.
0
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
25 nov. 2008 à 01:13
Bah dans limit.h c'est des constante qui sont utiliser.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844 > Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009
25 nov. 2008 à 01:18
Bien sûr qu'on code pas comme ça en vrai. Heureusement, sinon le code aurait pleins de vulnérabilités. Déjà quand on voit que tous les jours, une faille sur un code C sort au niveau des BOF.
Bref, tout ça pour dire que c'est un cas d'école. Et que le but de son exercice est de montrer que les types ont une limite (l'exercice demande pas de le calculer), mais de le montrer au moyen d'un programme.
En faisant une boucle en partant de 0 et en incrémentant le compteur, si au bout d'un certain nombre d'itérations on tombe sur un nombre négative, c'est bien qu'il y a une limite. Eh bien, justement c'est ça le but de son exercice, le mettre en évidence. Donc, pas d'utilisation des constantes. Inutile, dans ce type d'exercices.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
25 nov. 2008 à 06:32
Salut,

Oui mais comme je l'ai dit ce n'est pas très intéressant d'utiliser une bibli' standard.
Alors, on peut essayer comme ça?!
#include<stdio.h>

int main()
{
        printf("char min = %d, char max = %d\n",
                -(char)((unsigned char)~0>>1),
                (char)((unsigned char)~0>>1));
        printf("int min = %d, int max = %d\n",
                -(int)((unsigned int)~0>>1),
                (int)((unsigned int)~0>>1));
        return 0;
}
Résultat


1
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11
25 nov. 2008 à 00:16
Quand tu dépasses les limites d'une variable, exemple quand un tableau de char[7] tu mes écrit :
Bonjour
(Bonjour + \0 qui donne la fin de la chaine) tu te retrouves avec 8 caractères dans un espace alloué de 7 caractères, le 8 ème caractères va forcement s'inscrire quelque par mais dans une place qui lui n'est pas alloué, il se peut même que le caractère prêne la place en mémoire qui est déjà alloué à une autre variable, ça provoque des dérèglement très grave, c'est ce qu'on appelle on Buffer OverFlow .

Pour obtenir la taille en octet tu fais :
      printf("int = %d octets\n", sizeof(int)); // 4 octets
      printf("short = %d octets\n", sizeof(short)); // 2 octets
      printf("float = %d octets\n", sizeof(float)); // 4 octets
      printf("double %d octets\n\n", sizeof(double)); // 8 octets


Pour obtenir la taille maximum d'une variable tu fais :
taille_variable_octet * 8 (pour obtenir le nombre de bits) = x
2^x = taille maximum non signé 
x/2 = y
taille de la variable signé = -y à y


Exemple avec int :
4*8 = 32
2^32 = 4294967296 (Valeur non signé de int : unsigned int)
4294967296/2 = 2147483648

Valeur minimum int = -2147483648
Valeur maximum int = 2147483648 


Cependant les valeurs peuvent être différente celons les OS, par contre pour les float et les double ça ne marche pas :( .

Je ne peux pas tous savoir non plus :D .
Je chercherais demain là j'ai sommeil xD.

Si t'as besoin de plus d'aide je suis là demain à 17h15 <-> 17h45
0
La limite est de 2^32/2-1 ..allez savoir pourquoi le -1 mais il est bel et bien là~
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
26 juil. 2012 à 00:22
Bnmkt,

L'art de déterrer les topics ^^.
2^32/2-1 ???
Cela dépend du type de variable (et pas que de ça d'ailleurs).
Sinon 2^32/2 -1 Donc 2^31 -1 non ?
Et enfin pourquoi le -1 ? C'est très logique, c'est la valeur maximale obtenue avec 31 bits.
Par exemple si tu as 3 bits, le nombre maximum est 111 (soit 2^3 - 1 = 7).
Bref, rien de nouveau par rapport à la réponse de killian.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
25 nov. 2008 à 00:21
Salut,
Je te conseille de lire des tutoriaux sur le C. Sur internet, il y en a plein.
Sinon, par exemple, le type entier (int), est codé généralement sur quatre bytes (dépend de l'architecture). Mais dans tous les cas, il a donc une limite. Donc si tu prends par exemple une variable int, que tu incrémentes. Au bout d'un moment tu vas atteindre le nombre maximale qu'on puisse coder sur 4 bytes. Et après que se passe-t-il ? Il va passer en négatif (s'il est signé). Il y a donc eu overflow, Je te laisse faire le code à titre d'exercice ;).
Mais je te recommande avant tout de lire quelques tutoriaux sur le C. Sur le siteduzero, tu devrais trouver ça ;)
Cdlt
0
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11
25 nov. 2008 à 00:22
Oui mais il veut démontré comment on sait que c'est la valeur maximal j'ai trouvé pour les entier (avec Vista) je chercherais demain pour les décimaux.
Comme t'est sur XP refait le, je pense pas que ça change mais on sait jamais :° .
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
25 nov. 2008 à 00:28
Valeur maximale d'un entier:
0x8fffffff // dernier bit pas allumé, s'il est allumé c'est qu'on est négatif

Valeur minimale d'un entier:
0xf0000000

S'il est non signé, le max est 0xffffffff et le min est zero.....
0
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
25 nov. 2008 à 00:30
T'est à font dans l'exa toi xD
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
25 nov. 2008 à 00:33
Bah non. L'exercice est de montrer qu'il y a une limite. Pas de savoir c'est quoi la limite. Ce n'est pas pareil.
Sinon pour trouver la valeur maximale, si c'est codé sur 4 bytes, le calcul est rapide ;). De plus les limites sont présentes dans limits.h ^^.
Mais, là n'est pas le but de l'exercice, qui certes, pourrait être intéressant.
0
toto > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
25 nov. 2008 à 00:37
plutôt max 0x7FFFFFFF et min 0x80000000
0
Eclyps Messages postés 19 Date d'inscription jeudi 31 janvier 2008 Statut Membre Dernière intervention 13 janvier 2009 11 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
25 nov. 2008 à 00:38
T'es sûr ?
Tu doit avoir raison, je comprend mal l'anglais,
En tous cas il fallait dire ce que ça faisait un dépassement de mémoire :D
Mais c'est pas très intéressante de prendre direct des constantes directement faites sans algo autant démontré comment on obtient le chiffre ça serait pas plus intéressante pour le prof c'est un exercice après tous ?
0
Merci pour vos réponses, je vois déjà un peu plus vers ce que je dois aller... :)

Je vais travailler dessus demain...
0