Elmoricq Modérateur
| Je me permets d'ajouter des commentaires à ton code, ce sera plus simple je pense :
Code :
- # include <stdio.h>
- # include <stdlib.h>
- # include <malloc.h>
- #define MAXLENGTH 10
- typedef struct {
- char* nom;
- int no;
- }ID;
-
- int main(int argc , char *argv[])
- {
- int i,j,nm;
- char com;
- /* 1. le cast sur un void* est inutile
- 2. la multiplication est prioritaire sur l'addition, ta ligne ne
- fonctionne que parce que sizeof(char) == 1
- Tu aurais dû écrire : (MAXLENGTH+1) * sizeof(char)
- 3. Tu *DOIS* tester le retour de ton allocation memoire.
- Si malloc() echoue, tu auras droit a de mechantes surprises.
-
- char *ftmp = malloc((MAXLENGTH + 1) * sizeof *ftmp);
- if ( ftmp == NULL ) {
- ...
- }
- */
- char *ftmp=(char*)malloc(MAXLENGTH*sizeof(char)+1);
- /* Idem ici, cast inutile :
- ID *tab = malloc( MAXLENGTH * sizeof *tab) */
- ID* tab=(ID*)malloc(MAXLENGTH*sizeof(ID));
-
- if (tab==NULL)
- {
- /* Par convention, on imprime sur le flux d'erreur :
- fprintf(stderr, "malloc failed\\n" ); */
- printf("malloc failed\\n" );
- exit(1);
- }
-
- // Initialisation de tab
- tab[0].nom="Alexys"; tab[0].no=1235;
- tab[1].nom="Koebi"; tab[1].no=3345;
- tab[2].nom="Nido"; tab[2].no=8775;
- tab[3].nom="Fred"; tab[3].no=7422;
- tab[4].nom="Corinne"; tab[4].no=74520;
-
-
- printf("Entrez un nom : \\n" );
- /* SURTOUT PAS ! gets() NE DOIT PAS ETRE UTILISE !
- Cette fonction est un bug, elle n'est encore la
- que par souci de compatibilite.
- Ne jamais, jamais, jamais l'utiliser. Jamais.
- Utiliser fgets() : fgets(ftmp, MAXLENGTH, stdin); */
- gets(ftmp);
- printf("Entrez une commande : \n(i,s,r,q ?)\n" );
- com=getchar();
-
- /* tu ne passes qu'une seule fois par ton switch(), je pense qu'il te
- manque une boucle ou quelque chose... */
- switch (com)
- {
- case ('i'):
- // Queued
- for(j=0;j<MAXLENGTH;j++)
- {
- /* Non, pour la raison suivante : quand tu utilises
- malloc(), la memoire allouee contient n'importe quoi.
- Soit tu utilises calloc() et tu peux effectuer ce
- test, soit apres ton malloc() tu utilises memset() a
- la suite de ton malloc().
- Mais en l'etat actuel, tab[j] pourrait ne jamais
- retourner NULL, meme si la moitie de ton tableau
- n'est pas initialise.
- */
- if(tab[j].nom==NULL)
- {
- /* Hmm. Es-tu sur de vouloir faire ca ? Ici tu
- donnes l'adresse de ftmp a tab[j].nom. Ce qui fait
- que si ftmp change, tab[j].nom change aussi,
- puisque les deux pointent sur le meme bout de
- memoire.
- Il vaut mieux faire un strdup(), par exemple. */
- tab[j].nom=ftmp;
- printf("Quel est son numéro détudiant ? \\n" );
-
- /* evite scanf() si possible... ici, utilise plutot
- fgets() + strtol() pour convertir la chaine lue
- en un entier */
- scanf("%d",&nm);
- tab[j].no=nm;
- break;
- }
- }
- break;
- case ('s'):
- printf("find : %s\\n",ftmp);
-
- for(j=0;j<MAXLENGTH;j++)
- {
- /* tout d'abord, utiliser
- strcmp() pour comparer deux chaines de caracteres.
- Parce que la, tu ne fais que comparer deux pointeurs,
- ce qui est tout a fait different. En plus tu les
- compares mal, puisque tu compares les adresses des
- variables tab[j].nom et ftmp, et non leur contenu.
- Normalement, ton if n'est jamais vrai.
- Du coup, il est pas ici ton segfault */
- if(*(tab[j].nom)==*ftmp)
- printf("Etudiant numéro %d : %s \\n",tab[j].no, tab[j].nom);
- }
- break;
- case ('r'):
-
- break;
- case('q') : printf("Exit !\\n" ); exit;
- }
-
-
-
-
- /* Ah ouais mais non, il est *ICI* ton segfault :
- de i a MAXLENGTH, il n'y a que les 5 premieres cases
- d'initialisees.
- Le probleme c'est que tu lui demandes d'afficher des cases
- de tab[] qui pointent sur n'importe quoi en memoire. C'est un
- probleme parce que du coup il va lire ce qui est pointe par
- tes variables, et il y a de bonnes chances pour que soit l'adresse
- ne veuille rien dire, soit elle pointe sur un truc qui n'appartient
- pas a ton programme. Donc plantage.
-
- Ca c'est le cas 1. Parce que j'ai le sentiment que ton
- compilateur, qui est trop gentil, t'initialises tes variables a
- NULL par defaut. Ne compte jamais sur ce comportement, la norme
- veut que ce soit indefini. Mais, bref, dans tous les cas tu fais
- un printf() de NULL, et ca, ca mene aussi au segfault
-
- Bref, ne jamais utiliser de variables non initialisees */
- for(i=0;i<MAXLENGTH;i++)
- printf("étudiant no %d : %s\n",tab[i].no,tab[i].nom);
-
- free (ftmp);
- free (tab);
- return 0;
- }
|
EDIT : foutu forum et son interprétation des backslash Message édité par Elmoricq le 27-09-2005 à 13:28:19
|