Variable mémoire dépassement

truite -  
yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour! Par curiosité je voulais tester ce qu'il se passerait si j'assignais, à une variable, une valeur plus importante que sa capacité.

Par exemple, si je fais:
int nombre = 5000000000;

avec printf, j'obtiens un nombre totalement différent, quelque chose comme 700 millions et des poussières.

A quoi correspondent ces 700 millions ?

Par ailleurs, si je fais
char caractere = 'ab';

char caractere = 'abc';

avec un printf, j'obtiens juste le dernier caractère, c'est-à-dire un
b
dans le premier cas, et un
c
dans le second.

Où va le reste de la variable char qui n'est pas affiché ?

3 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    bonjour, n'hésite pas à montrer toutes tes instructions, ne nous laisse pas deviner comment tu fais appel à printf.
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      "quelque chose comme 700 millions et des poussières": n'hésite pas à partager le nombre exact que tu obtiens.
      0
      1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         
        tu sembles utiliser un compilateur très laxiste. as-tu posé tes questions au fournisseur de ce compilateur?
        0
      2. truite > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         
        bonjour,
        j'ai fait un
        printf("%d", nombre);

        et le nombre exact est 705032704

        (j'utilise visual studio 2019, pour le compilateur je n'en sais pas plus)
        0
  2. Pat
     
    Bonsoir,
    Normal
    Voila les déclaration en C
    Bool 0 1
    signed char -127 127
    unsigned char 0 255
    short -32 767 32 767
    unsigned short 0 65 535
    int -32 767 32 767
    unsigned int 0 65 535
    long -2 147 483 647 2 147 483 647
    unsigned long 0 4 294 967 295
    long long -9 223 372 036 854 775 807 9 223 372 036 854 775 807
    unsigned long long 0 18 446 744 073 709 551 615
    float -1 × 1037 1 × 1037
    double -1 × 1037 1 × 1037
    long double -1 × 1037 1 × 1037

    Pour votre variable la déclarer en unsigned long long

    Pour Char 1 Caractère pas plus
    i
    nt main(int argc, char *argv[])
    {
        char lettre = 'A';
    
        printf("%c\n", lettre);
    
        return 0;
    }
    

    Pour une chaine de caractères

    int main(int argc, char *argv[])
    {
        char chaine[] = "Salut"; // La taille du tableau chaine est automatiquement calculée
    
        printf("%s", chaine);
    
        return 0;
    } 
    
     


    Pour le fun
    int longueurChaine(const char* chaine);
    
    int main(int argc, char *argv[])
    {
        char chaine[] = "Salut";
        int longueur = 0;
    
        longueur = longueurChaine(chaine);
    
        printf("La chaine %s fait %d caracteres de long", chaine, longueur);
    
        
        return 0;
    }
    
    int longueurChaine(const char* chaine)
    {
        int nombreDeCaracteres = 0;
        char caractereActuel = 0;
    
        do
        {
            caractereActuel = chaine[nombreDeCaracteres];
            nombreDeCaracteres++;
        }
        while(caractereActuel != '\0'); // On boucle tant qu'on n'est pas arrivé à l'\0
    
        nombreDeCaracteres--; // On retire 1 caractère de long pour ne pas compter le caractère \0
    
        return nombreDeCaracteres;
    }
    0
    1. Pat
       
      CHAR(n) est un type de données qui respecte de la longueur dont n caractères stockée même si la longueur du texte est inférieure à n, il y aura alors un remplissage à blanc.
      Exemple :
      « toto » en CHAR(12) donne :

      "toto "
      VARCHAR(n) est un type de données de longueur variable avec au maximum n caractères stockée + stockage de la longueur du texte (en général sur 2 octets) et pas de remplissage à blanc.
      Exemple « toto » en VARCHAR(12) donne :

      04"toto"
      AVANTAGES / INCONVÉNIENTS :
      VARCHAR économise de l’espace si la longueur des données peut être grande et la taille du texte très fluctuante. Or plus on économise l’espace meilleures seront les performances .
      Mais si la données est voisine de la taille maximale ou fais toujours la taille maximale, alors avec les 2 octets pour stocker la taille c’est le contraire qui se produit.
      Par exemple pour un code postal, c’est stupide car il y aura toujours 5 caractères (en France) => VARCHAR = 7 octets, CHAR = 5 octets

      En sus, la recherche d’une colonne VARCHAR est plus complexe que la recherche d’une colonne CHAR au sein de la ligne composant la table. Son accès est donc plus lent, car il faut parcourir toutes les colonnes précédentes du fait de la longueur variable. Alors qu’avec une longueur fixe, il suffit de calculer l’offset par rapport au début de la ligne pour trouver immédiatement l’emplacement du premier caractère de la colonne de type CHAR (en fait pour optimiser les accès aux données, la plupart des SGBDR constituent les lignes des tables avec les colonnes de taille fixe en premier et les colonnes de taille variable en dernier de façon à ce que le repérage des colonnes de type fixe soit immédiat.

      Exemple complet de manipulations de variables


      #define taille_tableau 10  //Défini la taille du tableau des structures clients
      
      
       .............. définition d'une structure nommé enr
       struct enr 
       {
      		char   code[20];
      		char   matiere[30];
      		float  note;
       };
       struct enr fiche1;  // décalaration d'une variable fiche1 de type structure enr
       struct enr tablecode[20]; // un tableau de structure de type enr
       struct enr *ptr;		// un pointeur vers la structure enr
       
       .............. définition d'une structure nommé client
      
       //-- la structure CLIENT
      struct client
      {
       char ref[10+1];
       char nom[20+1];
       char prenom[20+1];
       char adresse[40+1];
       char cp[5+1];
       char ville[15+1];
       char tel[10+1];
      
      };
      
      //------Tableau de structure CLIENT
      struct client tab_client[taille_tableau]; 
      
      
      // variable globale compteur du nombre de client dans la base
      int nbre_client=0;	
      // structure de données comme paramétre d'entrée de la fonctione crire_client()
      void ecrire_client(struct client tmp) // Déclaration de la fonction Saisie des clients
      void saisie_client();         //Saisie des clients
      void affiche_client();        //Affiche les clients
       ...
       
      
      ...
      2. Accès aux membre de la structure en C/C++
      Un membre d'une structure est accédé par (nom_variable.nom_membre). Un membre d'une structure peut également être accédé par l'intermédiaire d'un pointeur (nom_pointeur->nom.membre).
       ........... Voir déclaration de structure plus haut
       
       struct enr *ptr;
       struct enr fiche1;
       
       int main()
       {
       
       
       .......................... Accès aux membre de la structure par une variable fiche1.................
       fiche1.note = 15.5;
       strpcy(fiche1.code, "MAT145");
       strpcy(fiche1.matiere, "Francais");
       printf("%s \n",fiche1.matiere);
       ...
       ........................... Accès aux membre de la structure par un pointeur ...................
       ptr = &fiche1		/* mettre l'adresse de fiche1 dans le pointeur ptr */
       ptr->note = 18.5;
       strcpy(ptr->code,"Laurent");
       strpcy(ptr->matiere, "Maths");
       printf("%s %f \n",ptr->matiere, ptr->note);
       ...
      
       ...........Accès aux membre de la structure par des fonctions. ...................
       .......
      
      	// appel fonction saisie de donneés client ;
      		saisie_client();	// saisie un premier client
      	 
      		gotoxy(20,47);     system("pause");
      		saisie_client();	// saisie un 2 client
      		affiche_client()		// affiche la liste des clients
      		getch();
      		return 0;
      }	 
      // fin programme principal 
       
       ......
      // *****Saisie de données CLIENT*****
       
       void saisie_client()
      {
      	struct client tmp_client;	//Déclaration de la structure temporaire client 
      	
      
      
      	char tel[20];	 
      	int x=25;		 // coordonnée de la Ligne x y
      	int y=13;		 
      	system("cls");
      	gotoxy(27,3);		 printf("- SAISIR UNE FICHE CLIENT -");	
      	fflush(stdin);	 //On vide la mémoire tampon
          gotoxy(x,y);    printf("Reference : ");     gets(tmp_client.ref);
      	gotoxy(25,47);   printf("                                  ");	
      	gotoxy(x,y+3);   printf("Nom : ");  		gets(tmp_client.nom);
      	gotoxy(x,y+6);   printf("Prenom : ");       gets(tmp_client.prenom);
      	gotoxy(x,y+9);   printf("Adresse : ");      gets(tmp_client.adresse);
      	gotoxy(x,y+12);   printf("Code postal : "); gets(tmp_client.cp);
      	gotoxy(x,y+15);	  printf("Ville : ");       gets(tmp_client.ville);
      	gotoxy(x,y+18);     printf("Telephone : "); gets(tel);
      
      	strcpy(tmp_client.tel,tel);	//On copie la variable tel dans la structure temporaire
      
      	// fonction ecrire_client()
      	//On écrit dans la base. Pour cela on envoi la structure temporaire de CLIENT	
      	ecrire_client(tmp_client); 
       }
       
       .....
       **************************************
      *****Enregistre les données CLIENT*****
      // une structure de données comme paramètre de la fonction ecrire_client()
      **************************************/
      void ecrire_client(struct client tmp)
      {	
       //Ecrit les données de la structure temporaire passé en paramètre (tmp)
       // dans la structure réelle de la base	
       strcpy(tab_client[nbre_client].ref,tmp.ref);
       strcpy(tab_client[nbre_client].nom,tmp.nom);
       strcpy(tab_client[nbre_client].prenom,tmp.prenom);
       strcpy(tab_client[nbre_client].adresse,tmp.adresse);
       strcpy(tab_client[nbre_client].cp,tmp.cp);
       strcpy(tab_client[nbre_client].ville,tmp.ville);
       strcpy(tab_client[nbre_client].tel,tmp.tel);
      
       gotoxy(23,40);textcolor(10);printf("Le client a ete ajoute dans la base");
       nbre_client++;	//Ajout d'un client dans la base
      
      }
      ............
      *****Afficher les clients*****
       parcourir un tableau de structure de données
      ****************************
      void affiche_client()
      {
      int i;		//Compteur de boucle
      int x=20;	//Represente la coordonnée de la Ligne
      int y=15;	//Represente la coordonnée de la Colonne
      
            for(i=0; i< nbre_client;i++)
      	  {
             system("cls");
             gotoxy(28,3);     printf("- AFFICHER LES CLIENTS -");
             gotoxy(x,y);      printf("Reference : %s ",tab_client[i].ref);
             gotoxy(x,y+3);    printf("Nom : %s ",tab_client[i].nom);
             gotoxy(x,y+6);    printf("Prenom : %s ",tab_client[i].prenom);
             gotoxy(x,y+9);    printf("Adresse : %s ",tab_client[i].adresse);
             gotoxy(x,y+12);   printf("Code postal : %s ",tab_client[i].cp);
             gotoxy(x,y+15);   printf("Ville : %s ",tab_client[i].ville);
             gotoxy(x,y+18);   printf("Telephone : %s ",tab_client[i].tel);
             gotoxy(30,40);    printf("Client %d sur %d",i+1,nbre_client);
             gotoxy(20,47);    system("pause");
             }
      } //fin affiche_client
      ..................

      ...
      0
  3. truite
     
    Je vois, merci pour vos réponses et vos liens, je vais peut-être pouvoir élucider le mystère! :)
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      merci, le moment venu, de marquer la discussion comme résolue.
      0