[C] Matrice sommet -> tableau sommet

Résolu/Fermé
macmat Messages postés 10 Date d'inscription jeudi 26 avril 2012 Statut Membre Dernière intervention 16 décembre 2012 - Modifié par macmat le 29/04/2012 à 13:37
macmat Messages postés 10 Date d'inscription jeudi 26 avril 2012 Statut Membre Dernière intervention 16 décembre 2012 - 29 avril 2012 à 22:41
Bonjour,
Je souhaiterais remplir un tableau de sommets, à partir d'une matrice d'arc. Le but étant d'éviter les doublons. J'aimerais comprendre pourquoi le code suivant ne fonctionne pas :

for(i=0;i<nbarc;i++){
for(j=0;j<2;j++){
for(k=0;k<nbarc;k++){
if (somtab[k]!=tab[i][j])
{
somtab = realloc (somtab,taille*sizeof(char));
somtab[k]=tab[i][j];
taille ++;
}
}
}
}
La matrice "tab" contient deux colonnes pour nbarc lignes, du type :
E a
E d
E f
a b
a c
...
Le but est de stocker uniquement les différents sommets, qui composent l'arc dans le tableau de caractère somtab, afin de ne pas gâcher d'espace mémoire, j'utilise la fonction realloc pour augmenter la taille, de somtab uniquement si le sommet n'est pas déjà présent dans celui-ci.
Il me semble qu'il s'agit ici d'un conflit mémoire, mais j'en suis pas sur, pourriez m'éclairer et m'expliquer d'où vient le problème s'il vous plaît.
Bien cordialement
Macmat

1 réponse

Utilisateur anonyme
29 avril 2012 à 15:36
Salut! est-ce que tu peux poster le reste de ton code stp?
Voilà ce que je vois qui pourrait te poser problème:
- premièrement, pourquoi incrémentes-tu taille après la réallocation de mémoire? Si tu initialises somtab, par exemple, à taille = 1 alors ton realloc ne fera rien d'utile...
- ensuite, si tu parcoures somtab dans ta boucle for, et que tu ne réalloues pas, k va sauter une position mémoire et tu vas te retrouver en débordement.

Il faudrait aussi penser à incrémenter nbarc.
0
macmat Messages postés 10 Date d'inscription jeudi 26 avril 2012 Statut Membre Dernière intervention 16 décembre 2012
29 avril 2012 à 16:47
Bonjour,
En fait je pensais incrémenter la taille après, afin d'augmenter au fur et à mesure la taille du tableau. L'incrémentation ne se réalise que si la consigne du if est respectée. Je pensais qu'il fallait parcourir somtab afin d'ajouter le sommet différent à la case suivant dans le tableau somtab.
Voici le reste du code :
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////Allocation dynamique tableau int////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
int *inttaballoc(int nbarc)
{
int *tabb;
tabb = calloc(nbarc, sizeof (int));
return tabb;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////Allocation dynamique tableau char////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
char *chartaballoc(int nbarc)
{
int nbl=2*nbarc;
char *tabb;
tabb = calloc(nbl, sizeof (char));
return tabb;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////Main/////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
int main(void){
int i,j,k, nbarc=0;
int taille;
int nbsommet=0;
int *tabl;
char *somtab;
char t[2],**tab,*ct;
FILE *f;
f=fopen("john.txt","r");
if(f){
nbarc=0;
/* compter nombre d'arc*/
while(fscanf(f,"%c %c %d\n",&t[0],&t[1],&j)!=EOF){
if(t[0]!=EOF) nbarc++;
printf("%c %c %d\n",t[0],t[1],j);
}
printf("\n");
tab=malloc(sizeof(char*)*nbarc);
if(tab) for(i=0;i<nbarc;i++) {
tab[i]=malloc(sizeof(char)*2);
if(!tab[i]) exit(1);
} else exit(1);

tabl = inttaballoc(nbarc);
rewind(f);
/* recup dans tab */
for(i=0;i<nbarc;i++){
fscanf(f,"%c %c %d\n",&tab[i][0],&tab[i][1],&tabl[i]);
}
/* affiche tab */
for(i=0;i<nbarc;i++)
printf("x:%c y:%c c:%d\n",tab[i][0],tab[i][1],tabl[i]);
printf("\n");

/*Compter le nombre de sommets*/
for(i=0;i<nbarc;i++){
for(j=0;j<2;j++){
for(k=0;k<nbarc;k++){
if (somtab[k]!=tab[i][j])
{
somtab = realloc (somtab,taille*sizeof(char));
somtab[k]=tab[i][j];
taille ++;
}
}
}
}
printf("%d\n", nbarc);
printf("%d\n", nbsommet);
/* free */
for(i=0;i<nbarc;i++)
free(tab[i]);
free(tab);
} else exit(1);
system("PAUSE");
return 0;
}
john.txt est un fichier de type :
E a 8
E d 10
E f 9
a b 4
a c 11
...
0
Utilisateur anonyme
29 avril 2012 à 18:06
Je ne sais pas si c'est pour cela que ça ne marche pas, mais tu n'as pas initialisé taille.
0
macmat Messages postés 10 Date d'inscription jeudi 26 avril 2012 Statut Membre Dernière intervention 16 décembre 2012
29 avril 2012 à 18:31
Après l'initialisation de taille, ça ne marche toujours pas. Le programme compile mais il bug quelque secondes après.
0
Utilisateur anonyme
29 avril 2012 à 18:54
En fait, plus je lis ton code plus il y a des trucs qui m'embêtent, je vais essayer de tous les lister ici:
- comme j'ai déjà dis, taille n'est pas initialisé avant la première utilisation.
- nbarc est initialisé deux fois, ce n'est pas nécessaire.
- nbsommet ne change jamais, au moment du printf il est toujours à 0.
- il faut allouer somtab avant de l'appeler. Pour ça le compilateur devrait gueuler.
- lors de l'allocation de tab, attention avec la multiplication dans un malloc, il peut y avoir des overflows. Pour éviter cela, préférer calloc.
- le pointeur ct n'est jamais utilisé.
0
Utilisateur anonyme
29 avril 2012 à 19:15
Aussi, si tu initialises
taille
, il vaudrait mieux d'abord l'incrémenter et ensuite faire realloc:
taille++;
somtab = realloc(somtab, taille);

Mais en fait je pense que ta triple imbrication de boucles for est fausse, repense-la.
0