Allocation d'un tableau dans une fonction

Allocation d'un tableau dans une fonction - C - Programmation

Marsh Posté le 19-08-2009 à 17:27:59    

Bonjour
 
Je me trouve bloqué depuis le début de l'aprem sur un détail qui vous semblera surement très simple mais qui me bloque complètement.  :pfff:
 
Je déclare un tableau. Puis j'utilise une fonction pour allouer l'espace nécessaire avec malloc, et le remplir avec des données lues dans un fichier. Le problème  se résume assez simplement : ça marche pas :sweat:  
 

Code :
  1. void maFonction(...){
  2.     double *ListeSeuils; /*declaration de mon tableau*/
  3.     int iNombreDeSeuils=0;
  4.     v_LectureListeSeuils(ccFichierDeSeuils, ListeSeuils, &iNombreDeSeuils)
  5.     (...)
  6.     free(ListeSeuils);
  7. }
  8. void v_LectureListeSeuils(char *ccNomFichier, double *ListeSeuils,int *iNombreDeSeuils){
  9.     (...)/*ouverture et parcourt du fichier pour connaître le nombre de ligne*/
  10.    
  11.     ListeSeuils = malloc(sizeof(double) * ((*iNombreDeSeuils)));  /*allocation du tableau*/
  12.     i=0;
  13.     while (fscanf(pfResultats,"%lf",&dSeuil)!=EOF){
  14.         ListeSeuils[i]=dSeuil; /*remplissage du tableau*/
  15.         i++;
  16.     }
  17. }


 
Or dès que je sort de ma fonction je perd les données!!!!
Merci de votre aide

Reply

Marsh Posté le 19-08-2009 à 17:27:59   

Reply

Marsh Posté le 19-08-2009 à 17:47:59    

Edit: Ma solution n'est peut-être pas bonne. Désolé.


Message édité par olivthill le 19-08-2009 à 17:53:50
Reply

Marsh Posté le 19-08-2009 à 17:51:30    

Ton compilateur doit hurler sur ça

Code :
  1. *ListeSeuils = (double *ListeSeuils)(malloc(sizeof(double) * (*iNombreDeSeuils)))

.

 

Corrige ça et tout ira bien;


Message édité par Taz le 19-08-2009 à 17:51:46
Reply

Marsh Posté le 19-08-2009 à 17:58:05    

Bin justement avec le code initial, il crie pas du tout le compilateur. Il dit même rien du tout. Mais par contre en changeant la ligne il aime pô :s

Reply

Marsh Posté le 19-08-2009 à 18:03:40    

vire ton param ListeSeuils et fais un return listeSeuils.
 
Et achète toi un libre sur les pointeurs.

Reply

Marsh Posté le 19-08-2009 à 18:09:26    

Pour un "return" oui j'y ai pensé mais j'ai un autre problème alors : là j'ai réduit la portée du problème : en réalité j'ai 2 tableaux à initialiser avec cette fonction. Deux tableaux de taille différentes. Je ne peux donc pas utiliser un "return" car je ne pourrais alors passer qu'un seul pointeur en retour. Y aurais-t-il une solution à mon problème?
 
PS : le bouquin noir avec un carré jaune dessus nommé couramment K&R est à 20 centimètres de mon PC, et ouvert!

Reply

Marsh Posté le 19-08-2009 à 19:24:12    

Deja pourquoi passer int iNombreDeSeuils=0 par pointeur ?

 

Ensuite, même si je crois que c'est plus utile avec un compilateur moderne, faudrait caster le retour du malloc en (double*).

 

En plus je ferais un test if (*ListSeuils = ---- malloc ---- blabla) == NULL avec un printf pour voir si y'a pas un probleme lors de l'allocation.

 

Apres, faut continuer l'investigation :o

Message cité 1 fois
Message édité par boblenain200 le 19-08-2009 à 19:24:27
Reply

Marsh Posté le 19-08-2009 à 19:44:37    

boblenain200 a écrit :

Deja pourquoi passer int iNombreDeSeuils=0 par pointeur ?


Probablement parce qu'il modifie cette variable
 

boblenain200 a écrit :

Ensuite, même si je crois que c'est plus utile avec un compilateur moderne, faudrait caster le retour du malloc en (double*).


Certainement pas !!! Ca masque les erreurs de programmation
 

boblenain200 a écrit :

Apres, faut continuer l'investigation :o


Pas besoin. Le problème est visible comme le nez au milieu de la figure
 

Duc_onlajoy a écrit :

Je ne peux donc pas utiliser un "return" car je ne pourrais alors passer qu'un seul pointeur en retour. Y aurais-t-il une solution à mon problème?


Toujours.
 
Ta fonction reçoit un pointeur à allouer et l'alloue. Un peu schématiquement comme ceci

Code :
  1. void allocate(double *pointeur)
  2. {
  3.     pointeur=malloc(n * sizeof(double));
  4. }


 
Et l'appel se fait schématiquement ainsi

Code :
  1. {
  2.     double *tableau;
  3.     allocate(tableau);
  4.     ...
  5.     free(tableau);
  6. }


 
Or, ne t'a-t-on pas appris qu'une fonction devant modifier une variable devait toujours recevoir l'adresse de cette variable ?
C'est valable que cette variable soit de type int

Code :
  1. void modif(int *pt)
  2. {
  3.     *pt=125;
  4. }
  5. int n=10;
  6. modif(&n);


 
Ou bien de type float...

Code :
  1. void modif(float *pt)
  2. {
  3.     *pt=125.17;
  4. }
  5. float n=10.0;
  6. modif(&n);


 
Ou bien de type "pointeur sur double"
 

Code :
  1. void allocate(double* *pt)
  2. {
  3.     (*pt)=malloc(n * sizeof(double))
  4. }
  5. double *tab;
  6. allocate(&tab);


 
PS: me semble que Taz a déjà donné la soluce mais... en moins explicite.
 

Duc_onlajoy a écrit :

PS : le bouquin noir avec un carré jaune dessus nommé couramment K&R est à 20 centimètres de mon PC, et ouvert!


Est-il lu ???

Message cité 1 fois
Message édité par Sve@r le 19-08-2009 à 19:45:14

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-08-2009 à 19:58:40    

Sve@r a écrit :


Probablement parce qu'il modifie cette variable
 


J'avais pas vu le commentaire :jap:
 

Sve@r a écrit :


Certainement pas !!! Ca masque les erreurs de programmation
 


Hum en quoi çà masque une erreur ? Le cast est juste pour éviter de mettre un void* sur un double* [:spamafote]

Reply

Marsh Posté le 19-08-2009 à 20:44:11    

boblenain200 a écrit :


Hum en quoi çà masque une erreur ? Le cast est juste pour éviter de mettre un void* sur un double* [:spamafote]


 
Ce sujet a déjà été longuement expliqué sur ce forum. Malheureusement j'ai trop chaud pour avoir envie de chercher.
 
Donc un bref résumé: au début, le pointeur universel était géré par un char *. Pointeur sur un caractère => arithmétique des pointeurs simple (de 1 en 1) et cast obligatoire lorsqu'on devait utiliser un autre type.
 
Puis le type "void *" est apparu. Type "pointeur universel". Facilement transformable en n'importe quoi d'autre et cast implicite => autorisé de mettre l'adresse d'un double (ou n'importe quoi d'autre) dans un void * sans cast. Donc déjà, pourquoi le cast ???
 
Par ailleurs, le malloc implique un prototype. Ce prototype est inscrit dans <stdlib.h>. Si ce prototype n'est pas présent, le compilo voyant apparaitre un malloc non prototypé dans le code le mettra int par défaut. Et si derrière il y a un cast, personne ne verra que le prototype n'y est pas. D'où l'erreur...
 
 
 
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-08-2009 à 20:44:11   

Reply

Marsh Posté le 20-08-2009 à 09:32:04    

M.E.R.C.I!
 
Alors maintenant je comprends bien.
@TAZ : en effet votre solution était la bonne mais je n'avais pas compris dans quel sens la prendre.
@Sve@r : Oui, je l'utilise ce livre. Même si je ne trouve pas qu'il soit le plus simple du monde. (peut-être le "manque" d'exemple)

Reply

Sujets relatifs:

Leave a Replay

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