Structure + Tableau dynamique en langage C

Structure + Tableau dynamique en langage C - C - Programmation

Marsh Posté le 26-11-2010 à 22:15:33    

Bonsoir,
 
Je débute en langage C et rencontre des difficultés pour un exo sur les structures et tableaux dynamiques.
 
Il faut définir une structure Vecteur qui contient la taille et le tableau de ses coefficients réels (double).
 
Ensuite allouer et desallouer dynamiquement Vecteur à l'aide de deux fonctions dont voici les prototypes :
 
Vecteur *alloc_Vecteur(int n);
Vecteur *free_Vecteur(Vecteur *V);
 
J'ai donc crée la structure Vecteur et les deux fonctions mais avant de les tester, j'ai essayé d'affecter "à la main" quelques cases du tableau contenu dans la structure que j'ai crée.
 
Comme ceci :
 

Code :
  1. int main()
  2. int n=8; Vecteur *V1;
  3.    V1=alloc_Vecteur(n);
  4.    V1->t[1]=9;
  5.    printf("%f", V1->t[1]);
  6. }


 
La compilation réussit mais le programme plante à l'execution.
 
Bizarrement, lorsque j'affecte une case du tableau autre que la 0ème ou la 1ère, comme
ceci,
 

Code :
  1. int main()
  2. int n=8; Vecteur *V1;
  3.    V1=alloc_Vecteur(n);
  4.    V1->t[3]=9;
  5.    printf("%f", V1->t[3]);
  6. }


 
               , et bien le programme s'exécute cette fois-ci correctement et m'affiche
9.000000.
 
J'essaye de trouver l'origine du problème depuis des heures, en vain.
 
Si vous pouviez regarder mon programme et m'indiquer les erreurs, cela me serait d'une
grande utilité.
 
Je vous ajoute le contenu de mon programme  :
 
 
 

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <limits.h>
  4. #include <float.h>
  5. #include <stdlib.h>
  6. #include <stddef.h>
  7. #include <assert.h>
  8. typedef struct{int taille; double*t;}Vecteur;
  9. Vecteur *alloc_Vecteur(int n)
  10. {  Vecteur *V = NULL;
  11.    assert( n>0);
  12.    V = (Vecteur*)malloc(sizeof(Vecteur));
  13.    V->taille=n;
  14.    V->t=(double*)malloc(n*sizeof(double*));
  15. }
  16. Vecteur *free_Vecteur(Vecteur *V)
  17. {
  18.   if ( V != NULL )
  19.   {  free( V->t );
  20.      free(V);
  21.   }
  22.   return(NULL);
  23. }
  24. void affecte_Vecteur(double valeur, Vecteur *V, int i)
  25. {
  26.   assert ( ( V!=NULL ) & ( i>=1 ) );
  27.   V->t[i-1]=valeur;
  28. }
  29. int main()
  30. { int n=8, valeur =7;
  31.   Vecteur *V1;
  32.   V1=alloc_Vecteur(n);
  33.   V1->t[1]=9;
  34.   printf("%f", V1->t[1]);
  35.   V1=free_Vecteur(V1);
  36. system("pause" );
  37. return 0;
  38. }


 
 
Merci d'avance !

Reply

Marsh Posté le 26-11-2010 à 22:15:33   

Reply

Marsh Posté le 26-11-2010 à 22:26:59    

Quand tu alloues V->t tu fais n fois la taille d'un pointeur (double *). Essaye plutôt avec sizeof(double).

Reply

Marsh Posté le 26-11-2010 à 22:34:37    

Et bien tout d'abord merci pour ta réponse.
 
Je viens d'enlever l'étoile à l'instant mais cela n'entraine aucun changement apparemment :
 
Comme tout à l'heure, la compilation se déroule bien :
 
http://www6.pic-upload.de/26.11.10/z2j39co9bskg.jpg
 
Par contre, j'ai toujours cette même erreur à l'execution :  
 
http://www6.pic-upload.de/26.11.10/km56gfzplft.jpg
 
 
 
J'ai le même message d'erreur en executant avec Cygwin :
 
 
http://www6.pic-upload.de/thumb/26.11.10/4l5rrf1vgrz6.jpg


Message édité par fabe51 le 26-11-2010 à 22:38:36
Reply

Marsh Posté le 26-11-2010 à 22:40:12    

Faudrait retourner V dans ta fonction d'alloc aussi. :)

Reply

Marsh Posté le 26-11-2010 à 22:50:34    

Ma foi je ne saurais te remercier assez. J'ai passé un temps fou à essayer de trouver mon erreur et je n'aurais surement pas pu trouvé sans ton aide. Du moins pas ce soir en tout cas  :)  
 
En effet ma fonction alloc ne renvoyait rien. J'ai mis un return V; et le programme tourne parfaitement.
 
Par contre en mettant return(NULL); à la place de return V; le programme envoie la même erreur que tout à l'heure. Saurais-tu pourquoi ?
 
En tous merci beaucoup !!


Message édité par fabe51 le 26-11-2010 à 22:50:49
Reply

Marsh Posté le 26-11-2010 à 22:58:11    

Si tu retournes NULL ta variable V (dans la fonction main()) va valoir NULL.
 
Si tu fais V->t ensuite, tu déréférences NULL. Autrement dit tu vas lire à l'adresse 0 de ta mémoire et ton système ne te laisse (heureusement) pas faire ça.


Message édité par regexp42 le 26-11-2010 à 22:58:29
Reply

Marsh Posté le 26-11-2010 à 23:08:13    

Ah d'accord je vois.  
 
Je me pose encore une dernière petite question.
 
Dans mon programme la taille du tableau t a été fixé à 8 ( dans le main int n=8 ).  
 
Si je crée une boucle qui m'affiche ces 8 cases de t ( t[0], t[1], ..., t[7] ) comme ceci :
 

Code :
  1. for ( i=0; i<n; i++)
  2.   {
  3.   V1->t[i]=5;
  4.   printf("%f\n", V1->t[i]);
  5.   }


 
     , il m'affiche ces valeurs sans problème.
 
Par contre il s'agit d'un tableau dynamique. A priori rien ne m'empêche d'afficher ce qu'il y a dans la case t[8] ou t[9]... n'est-ce pas ?
 
Ou bien la taille du tableau n'a pas du tout été fixé à 8, j'ai juste alloué de la mémoire pour un tableau de 8 cases...


Message édité par fabe51 le 26-11-2010 à 23:15:03
Reply

Marsh Posté le 26-11-2010 à 23:15:29    

Si tu n'alloues que 8 cases, tu peux pas aller taper plus loin qu'à 7. Tu peux lire des trucs bizarres plutôt que de segfauter de temps en temps mais y'a pas grand interêt.
Enfin je comprends pas vraiment ce que tu veux y lire.

Reply

Marsh Posté le 26-11-2010 à 23:24:01    

J'avoue n'avoir pas été très clair.
 
Je me demandais juste où se situe la limite du tableau dynamique que j'ai crée. C'est à dire quelle est sa dernière case.
 
Je sais que pour un tableau non dynamique de taille 5 (par exemplaire), tenter d'accéder à la case 6 n'a pas de sens puisqu'elle n'existe pas. Et on aura droit bien sûr à une erreur.
 
Enfin, tu viens de me donner la réponse juste avant.
J'aurais droit aussi à une erreur ou je pourrais lire à peu près n'importe quoi.
 
Merci encore !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed