Variable mémoire dépassement

Fermé
truite - Modifié le 29 janv. 2021 à 22:05
yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024 - 30 janv. 2021 à 20:34
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é ?
A voir également:

3 réponses

yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024 Ambassadeur 1 557
29 janv. 2021 à 22:11
bonjour, n'hésite pas à montrer toutes tes instructions, ne nous laisse pas deviner comment tu fais appel à printf.
0
yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024 1 557
29 janv. 2021 à 22:12
"quelque chose comme 700 millions et des poussières": n'hésite pas à partager le nombre exact que tu obtiens.
0
yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024 1 557 > yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024
29 janv. 2021 à 22:15
tu sembles utiliser un compilateur très laxiste. as-tu posé tes questions au fournisseur de ce compilateur?
0
truite > yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024
Modifié le 29 janv. 2021 à 23:58
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
Utilisateur anonyme > truite
30 janv. 2021 à 07:48
Bonjour

Visual studio ne dispose pas de compilateur C.

Voir ce message de Dalfb https://forums.commentcamarche.net/forum/affich-37065516-visual-studio#4 (comme la discussion entière ne fait que 5 messages, je t'invite à la lire complètement).

D'autre part, pour du "vrai" C, voir cet article au chapitre "Débordement" https://fr.wikibooks.org/wiki/Programmation_C/Types_de_base#D%C3%A9bordement
0
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
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
Je vois, merci pour vos réponses et vos liens, je vais peut-être pouvoir élucider le mystère! :)
0
yg_be Messages postés 23412 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 28 décembre 2024 1 557
30 janv. 2021 à 20:34
merci, le moment venu, de marquer la discussion comme résolue.
0