A voir également:
- Erreur à l'exécution mais pas à la compil
- Erreur 0x80070643 - Accueil - Windows
- Erreur 0x80070643 Windows 10 : comment résoudre le problème de la mise à jour KB5001716 - Accueil - Windows
- Erreur 1001 outlook - Accueil - Bureautique
- Erreur 3005 france tv - Forum TV & Vidéo
- Erreur 5000 france tv - Forum iPhone
6 réponses
manu_
Messages postés
7
Date d'inscription
mercredi 8 juin 2005
Statut
Membre
Dernière intervention
11 juin 2005
8 juin 2005 à 17:11
8 juin 2005 à 17:11
Bonjour,
le problème est que quand tu déclares tes buffers, tu ne fais que déclarer un pointeur sur un entier, sans que ce pointeur soit initialisé (à la valeur de l'adresse d'un entier).
Par la suite, tu tenteras d'écrire tes nombres aléatoires à un emplacement en mémoire que tu ne connais pas, et sur lequel il t'est interdit par le système d'exploitation d'écrire.
Il faut donc que tu déclares un pointeur sur un tableau de 50 entiers :
int buffer1[50] ; //vecteur de départ
Autre solution : te servir de la fonction malloc.
int *buffer1; //vecteur de départ
buffer=(int*)malloc(sizeof(int)*50) ;
La fonction malloc renvoie un pointeur sur un tableau (plus généralement sur une zone en mémoire) de n octets, n étant la valeur de son paramètre. Cette opération s'appelle l'allocation mémoire. Si l'allocation échoue (parce que tu as demandé par exemple une zone mémoire trop grande), la valeur retournée par
le problème est que quand tu déclares tes buffers, tu ne fais que déclarer un pointeur sur un entier, sans que ce pointeur soit initialisé (à la valeur de l'adresse d'un entier).
Par la suite, tu tenteras d'écrire tes nombres aléatoires à un emplacement en mémoire que tu ne connais pas, et sur lequel il t'est interdit par le système d'exploitation d'écrire.
Il faut donc que tu déclares un pointeur sur un tableau de 50 entiers :
int buffer1[50] ; //vecteur de départ
Autre solution : te servir de la fonction malloc.
int *buffer1; //vecteur de départ
buffer=(int*)malloc(sizeof(int)*50) ;
La fonction malloc renvoie un pointeur sur un tableau (plus généralement sur une zone en mémoire) de n octets, n étant la valeur de son paramètre. Cette opération s'appelle l'allocation mémoire. Si l'allocation échoue (parce que tu as demandé par exemple une zone mémoire trop grande), la valeur retournée par
manu_
Messages postés
7
Date d'inscription
mercredi 8 juin 2005
Statut
Membre
Dernière intervention
11 juin 2005
8 juin 2005 à 22:26
8 juin 2005 à 22:26
Excuse moi pour l'interruption. Voilà la suite :
...la fonction malloc est NULL. De plus, après l'utilisation d'une zone mémoire allouée avec malloc, il faut avant de terminer ton programme la libérer au moyen de la fonction free. Son unique paramètre est le pointeur préalablement initialisé avec malloc.
Autre erreur aussi importante : l'utilisation des pointeurs i et j est mauvaise. Le fait que tu déclares un pointeur i ne signifie pas que l'adresse contenue dans i soit l'adresse d'un entier présent en mémoire. La solution est :
int i ;
int j ;
...
remplir(buffer1,&i) ;
...
vider(buffer1,buffer2,&j,&i)
...
aff(buffer2,&j,&i) ;
...
Autre erreur dans printf("%3d",buffer1); : buffer1 est un tableau d'entier et non un entier. L'instruction correcte est printf("%3d",buffer1[k]);
Voilà !
Au niveau de l'algorithme j'ai pas trop regardé, mais en général je trouve que tu te compliques la vie avec tes pointeurs ; tes fonctions ont un "effet de bord" pas nécessaire et qui alourdit considérablement le code.
Préfère les variables locales à l'intérieur de tes fonctions. A ta demande je peux te proposer mon écriture de ton programme.
En tous les cas bonne programmation !
...la fonction malloc est NULL. De plus, après l'utilisation d'une zone mémoire allouée avec malloc, il faut avant de terminer ton programme la libérer au moyen de la fonction free. Son unique paramètre est le pointeur préalablement initialisé avec malloc.
Autre erreur aussi importante : l'utilisation des pointeurs i et j est mauvaise. Le fait que tu déclares un pointeur i ne signifie pas que l'adresse contenue dans i soit l'adresse d'un entier présent en mémoire. La solution est :
int i ;
int j ;
...
remplir(buffer1,&i) ;
...
vider(buffer1,buffer2,&j,&i)
...
aff(buffer2,&j,&i) ;
...
Autre erreur dans printf("%3d",buffer1); : buffer1 est un tableau d'entier et non un entier. L'instruction correcte est printf("%3d",buffer1[k]);
Voilà !
Au niveau de l'algorithme j'ai pas trop regardé, mais en général je trouve que tu te compliques la vie avec tes pointeurs ; tes fonctions ont un "effet de bord" pas nécessaire et qui alourdit considérablement le code.
Préfère les variables locales à l'intérieur de tes fonctions. A ta demande je peux te proposer mon écriture de ton programme.
En tous les cas bonne programmation !
Salut,
Merci pour tes corrections, pour le printf("%3d",buffer1[k]); je ne sais pas comment j'ai fais pour ne pas le voir!!! (sans doute le stress puisque c'était mon examen!!!)
Sinon pour la fonction malloc, je ne l'ai jamais utilisé. Je savais qu'elle existait, mais sans plus.
Toujours pour malloc, pour résumer on réserve (dans mon cas) 50 emplacements mémoire et si j'ai bien compris c'est le même principe que si on faisait: int buffer1[50]...
Par contre avec int *buffer1, on réserve 1 seul emplacement mémoire et les 49 autres se placent n'importe où. C'est bien ça?
Encore une chose, la consigne voulait que les variables soit déclarée localement à la fonction main, personnellement je n'aurai pas fais comme ça non plus...
Sinon je te remercie pour ton aide et si tu pouvais m'écrire ton code
se ne serai pas de refus... Bonne programmation à toi aussi.
Merci pour tes corrections, pour le printf("%3d",buffer1[k]); je ne sais pas comment j'ai fais pour ne pas le voir!!! (sans doute le stress puisque c'était mon examen!!!)
Sinon pour la fonction malloc, je ne l'ai jamais utilisé. Je savais qu'elle existait, mais sans plus.
Toujours pour malloc, pour résumer on réserve (dans mon cas) 50 emplacements mémoire et si j'ai bien compris c'est le même principe que si on faisait: int buffer1[50]...
Par contre avec int *buffer1, on réserve 1 seul emplacement mémoire et les 49 autres se placent n'importe où. C'est bien ça?
Encore une chose, la consigne voulait que les variables soit déclarée localement à la fonction main, personnellement je n'aurai pas fais comme ça non plus...
Sinon je te remercie pour ton aide et si tu pouvais m'écrire ton code
se ne serai pas de refus... Bonne programmation à toi aussi.
manu_
Messages postés
7
Date d'inscription
mercredi 8 juin 2005
Statut
Membre
Dernière intervention
11 juin 2005
10 juin 2005 à 16:41
10 juin 2005 à 16:41
Salut !
D'abord, quand ton prof demande des variables locales, je pense qu'il ne parle que des buffers. Il n'y a aucun interêt à déclarer des variables dont l'utilisation sera faite dans d'autres fonctions. En revanche, et c'est ce que ton prof ne voulait pas, c'est que tu définisses en global tes buffers et d'autres variables ; c'est une programmation bien moins propre et moins "esthétique".
Précision : avec int *buffer1 tu ne déclares qu'une variable pouvant contenir l'adresse d'un entier, mais tu ne réserves pas de place pour cet entier sur lequel tu "voudrais" pointer.
C'est ensuite à toi de réserver de la place pour tes 50 entiers, et d'affecter à buffer1 l'adresse du premier entier réservé.
Ensuite, il existe une petite différence avec int buffer1[50] et l'utilisation du malloc : avec la première solution, ton programme executable contiendra l'emplacement de ces 50 entiers (si tu regardes la taille de ton fichier EXE en réservant 5000 entiers, celui-ci sera plus gros qu'avec 50 entiers). L'utilisation de malloc "retarde" cette réservation : c'est lors de l'execution de ton programme que celui-ci va demander à Windows de chercher quelque part en mémoire une zone pour 50 entiers, et Windows te renverra un pointeur sur une telle zone (ou NULL si il n'a pas pu en trouver). D'ailleurs que tu demandes 50 ou 50000 entiers dans un malloc, ton executable aura la même taille.
Voilà, j'pense que je t'enverrai d'ici peu le code source sans l'utilisation de malloc (ce sera à toi de faire une autre version avec !).
Salut !
D'abord, quand ton prof demande des variables locales, je pense qu'il ne parle que des buffers. Il n'y a aucun interêt à déclarer des variables dont l'utilisation sera faite dans d'autres fonctions. En revanche, et c'est ce que ton prof ne voulait pas, c'est que tu définisses en global tes buffers et d'autres variables ; c'est une programmation bien moins propre et moins "esthétique".
Précision : avec int *buffer1 tu ne déclares qu'une variable pouvant contenir l'adresse d'un entier, mais tu ne réserves pas de place pour cet entier sur lequel tu "voudrais" pointer.
C'est ensuite à toi de réserver de la place pour tes 50 entiers, et d'affecter à buffer1 l'adresse du premier entier réservé.
Ensuite, il existe une petite différence avec int buffer1[50] et l'utilisation du malloc : avec la première solution, ton programme executable contiendra l'emplacement de ces 50 entiers (si tu regardes la taille de ton fichier EXE en réservant 5000 entiers, celui-ci sera plus gros qu'avec 50 entiers). L'utilisation de malloc "retarde" cette réservation : c'est lors de l'execution de ton programme que celui-ci va demander à Windows de chercher quelque part en mémoire une zone pour 50 entiers, et Windows te renverra un pointeur sur une telle zone (ou NULL si il n'a pas pu en trouver). D'ailleurs que tu demandes 50 ou 50000 entiers dans un malloc, ton executable aura la même taille.
Voilà, j'pense que je t'enverrai d'ici peu le code source sans l'utilisation de malloc (ce sera à toi de faire une autre version avec !).
Salut !
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
manu_
Messages postés
7
Date d'inscription
mercredi 8 juin 2005
Statut
Membre
Dernière intervention
11 juin 2005
10 juin 2005 à 17:05
10 juin 2005 à 17:05
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
//prototype de la fonction remplir
void remplir(int *tab1) ;
//prototype de la fonction vider. Valeur de retour : le nombre d'éléments effectivement copiés dans tab2
int vider(int *tab1, int *tab2) ;
//prototype de la fonction aff
void aff(int *tab,int NbElemAAfficher) ;
int main()
{
int buffer1[50] ; //vecteur de départ
int buffer2[50] ; //vecteur résultat
int NbElemB2 ; // Le nombre d'éléments de buffer2
char choix ;
NbElemB2=0 ; // Pour éviter d'afficher le buffer2 quand il n'est pas rempli
do
{
//clrscr() ;
printf("\n\n\tMENU\n\n") ;
printf("1.Remplir le buffer\n") ;
printf("2.Tampon resultat\n") ;
printf("3.Afficher le tampon\n") ;
printf("4.Quitter\n\n") ;
printf("\n\n\nFaites un choix: ");
choix=getch();
printf("%c",choix);
switch (choix)
{
//Remplir le tampon
case'1':
printf("\nRemplissage du tampon...");
remplir(buffer1) ;
printf("OK !\n") ;
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//Tampon résultat
case'2':
printf("Vidage du tampon 1 dans le tampon2...") ;
NbElemB2=vider(buffer1,buffer2) ;
printf("\n\n\nLe tampion resultat est rempli\n\n\n");
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//afficher le tampon
case'3':
printf("\n\n\nVoici le tampon resultat:\n\n\n");
aff(buffer2,NbElemB2);
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//quitter
case'4':
break;
}
}
while(choix!='4') ;
return 0;
}
//fonction remplir
void remplir(int *tab1)
{
int i ;
srand(time(NULL));
for(i=0;i<50;i++) //on remplit le buffer
{
tab1[i]=rand()%100;
}
}
//fonction vider
int vider(int *tab1, int *tab2)
{
int i ;
int j ;
j=0 ;
for(i=0;i<50;i++)
{
if (tab1[i]<=91 && tab1[i]>=65 || tab1[i]==32)
{ //on trie le buffer
tab2[j]=tab1[i];
j++;
}
}
return j ;
}
void aff(int *tab,int NbElemAAfficher)
{
int i ;
for(i=0;i<NbElemAAfficher;i++) //on affiche le buffer final
{
printf("%c ",tab[i]);
}
}
Voilà, y'a peut-être un peu trop de \n, mais sinon, cà marche nickel !
#include<stdlib.h>
#include<conio.h>
#include<time.h>
//prototype de la fonction remplir
void remplir(int *tab1) ;
//prototype de la fonction vider. Valeur de retour : le nombre d'éléments effectivement copiés dans tab2
int vider(int *tab1, int *tab2) ;
//prototype de la fonction aff
void aff(int *tab,int NbElemAAfficher) ;
int main()
{
int buffer1[50] ; //vecteur de départ
int buffer2[50] ; //vecteur résultat
int NbElemB2 ; // Le nombre d'éléments de buffer2
char choix ;
NbElemB2=0 ; // Pour éviter d'afficher le buffer2 quand il n'est pas rempli
do
{
//clrscr() ;
printf("\n\n\tMENU\n\n") ;
printf("1.Remplir le buffer\n") ;
printf("2.Tampon resultat\n") ;
printf("3.Afficher le tampon\n") ;
printf("4.Quitter\n\n") ;
printf("\n\n\nFaites un choix: ");
choix=getch();
printf("%c",choix);
switch (choix)
{
//Remplir le tampon
case'1':
printf("\nRemplissage du tampon...");
remplir(buffer1) ;
printf("OK !\n") ;
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//Tampon résultat
case'2':
printf("Vidage du tampon 1 dans le tampon2...") ;
NbElemB2=vider(buffer1,buffer2) ;
printf("\n\n\nLe tampion resultat est rempli\n\n\n");
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//afficher le tampon
case'3':
printf("\n\n\nVoici le tampon resultat:\n\n\n");
aff(buffer2,NbElemB2);
printf("\n\n\n\tAppuyer sur une touche pour continuer...");
getchar();
break;
//quitter
case'4':
break;
}
}
while(choix!='4') ;
return 0;
}
//fonction remplir
void remplir(int *tab1)
{
int i ;
srand(time(NULL));
for(i=0;i<50;i++) //on remplit le buffer
{
tab1[i]=rand()%100;
}
}
//fonction vider
int vider(int *tab1, int *tab2)
{
int i ;
int j ;
j=0 ;
for(i=0;i<50;i++)
{
if (tab1[i]<=91 && tab1[i]>=65 || tab1[i]==32)
{ //on trie le buffer
tab2[j]=tab1[i];
j++;
}
}
return j ;
}
void aff(int *tab,int NbElemAAfficher)
{
int i ;
for(i=0;i<NbElemAAfficher;i++) //on affiche le buffer final
{
printf("%c ",tab[i]);
}
}
Voilà, y'a peut-être un peu trop de \n, mais sinon, cà marche nickel !
Salut,
je te remercie pour le code et pour tout le reste. Pour ce qui est de la précision c'est exactement ce que je voulais savoir, je ferais donc une autre version avec le fameux malloc (peut-être pas tout de suite parce que j'ai encore des exams mais je le ferais)...
Encore merci et comme j'ai compris je pense qu'il n'y aura pas de prochaine fois... j'espère!!!
Salut.
je te remercie pour le code et pour tout le reste. Pour ce qui est de la précision c'est exactement ce que je voulais savoir, je ferais donc une autre version avec le fameux malloc (peut-être pas tout de suite parce que j'ai encore des exams mais je le ferais)...
Encore merci et comme j'ai compris je pense qu'il n'y aura pas de prochaine fois... j'espère!!!
Salut.