Pointeur en argument -> obtention de la taille de l'élément pointé?

Pointeur en argument -> obtention de la taille de l'élément pointé? - C - Programmation

Marsh Posté le 28-11-2007 à 20:44:54    

Je voudrais faire passer des pointeurs dans les arguments de mes fonctions. Ces pointeurs pointeraient vers des pointeurs chaines de caractères.
 

Code :
  1. type fonction(char** pointeur_chaine,...);


 
Dans cette fonction je pourrais donc accéder à chaque chaine de caractère par:
 

Code :
  1. pointeur_chaine[i]


 
Les pointeurs passés en arguments seraient crées et utilisés de cette manière:
 

Code :
  1. pointeur_chaine=malloc(nb_chaines*sizeof(char*));
  2. /*[...]test du retour malloc*/
  3. for(i=0;i<nb_chaines;i++)
  4. {
  5.     pointeur_chaine[i]=malloc((nb_caracteres+1)*sizeof(char));
  6.     /*[...]test du retour malloc*/
  7. }
  8. /*[...]remplissage des chaines*/
  9. fonction(pointeur_chaine);


 
Mon problème: Si je me situe à l'intérieur de ma fonction, comment connaitre le nombre de chaines pointés par pointeur_chaines? Pour moi c'est impossible. En fait sizeof(pointeur_chaine) me donnerait la taille de la mémoire contenant l'adresse, 4 octets chez moi.
 
Les solutions:  
 

  • Créer non pas un pointeur de pointeur de char mais un tableau de pointeur de char. Je pourrais peut être accéder aux nombre de chaines grâce à sizeof(tableau). Mais je ne peux pas créer de tableaux, je veux rester en allocation dynamique.


  • Créer une structure avec mon pointeur de pointeur de char plus un int indiquant le nombre de chaines pointées par le pointeur.


Si vous avez des solutions merci d'avance  :jap:

Message cité 1 fois
Message édité par ngkreator le 28-11-2007 à 20:46:34
Reply

Marsh Posté le 28-11-2007 à 20:44:54   

Reply

Marsh Posté le 28-11-2007 à 20:52:34    

ngkreator a écrit :

Mon problème: Si je me situe à l'intérieur de ma fonction, comment connaitre le nombre de chaines pointés par pointeur_chaines? Pour moi c'est impossible.


 
Exact.
 

ngkreator a écrit :

En fait sizeof(pointeur_chaine) me donnerait la taille de la mémoire contenant l'adresse, 4 octets chez moi.


 
Exact aussi.
 

ngkreator a écrit :

Les solutions:  
 

  • Créer non pas un pointeur de pointeur de char mais un tableau de pointeur de char. Je pourrais peut être accéder aux nombre de chaines grâce à sizeof(tableau). Mais je ne peux pas créer de tableaux, je veux rester en allocation dynamique.


  • Créer une structure avec mon pointeur de pointeur de char plus un int indiquant le nombre de chaines pointées par le pointeur.


Si vous avez des solutions merci d'avance  :jap:


 
Solutions les plus courantes :  

  • ajouter la taille en paramètre de la fonction
  • terminer la zone par une occurrence à NULL, comme ça tu boucles jusqu'à trouver l'entrée nulle.

Reply

Marsh Posté le 28-11-2007 à 21:05:31    

Elmoricq a écrit :


 
Solutions les plus courantes :  

  • ajouter la taille en paramètre de la fonction
  • terminer la zone par une occurrence à NULL, comme ça tu boucles jusqu'à trouver l'entrée nulle.

La 2ème solution me plait. Pour être sûr d'avoir bien compris je peux soit:
Avoir x chaines pointées par mon pointeur. Je crée une (x+1)ème chaine de 1 caratère NULL?
Avoir x chaines pointées, puis initialiser à NULL le (x+1)ème pointeur?

Message cité 1 fois
Message édité par ngkreator le 28-11-2007 à 21:05:55
Reply

Marsh Posté le 29-11-2007 à 01:06:48    

la solution:
- fait leur depart à une zone de memoire qui vous connait leur adresse  
et puis fait l'alocation memoire a l'aide du fonction realoc qui vous permet d'aloce d'une facon contigue et apres que vous continue de la boucle for regarde l'adresse de dernier element insere.

Reply

Marsh Posté le 29-11-2007 à 01:35:27    

Et la solution à la "API Windows" : chaines à double zéro terminal ?
chaine1\0chaine2\0chaine3\0\0
tu parcours ton bloc de données et quand le début de la chaine suivante vaut 0 t'as fini.
Pas forcément propre ni efficace mais ca peut faire la blague.
 

Reply

Marsh Posté le 29-11-2007 à 08:27:34    

c'est quand même plus simple de passer la taille ou alors de terminer ton char** par un NULL

Reply

Marsh Posté le 29-11-2007 à 09:42:13    

compilateur_C a écrit :

la solution:
- fait leur depart à une zone de memoire qui vous connait leur adresse  
et puis fait l'alocation memoire a l'aide du fonction realoc qui vous permet d'aloce d'une facon contigue et apres que vous continue de la boucle for regarde l'adresse de dernier element insere.

J'avoue ne pas avoir compris.
 

SquiZZ a écrit :

tu parcours ton bloc de données et quand le début de la chaine suivante vaut 0 t'as fini.


Donc ça correspondrait à la 1 ème proposition:

ngkreator a écrit :

Avoir x chaines pointées par mon pointeur. Je crée une (x+1)ème chaine de 1 caratère NULL?


 

Taz a écrit :

c'est quand même plus simple de passer la taille ou alors de terminer ton char** par un NULL


Donc ça correspondrait à la 2 ème proposition:

ngkreator a écrit :

Avoir x chaines pointées, puis initialiser à NULL le (x+1)ème pointeur?


Passer la taille en argument je trouve ça moins "élégant" et moins pratique pour l'utilisation de la fonctiona après.
 
Donc je vais utiliser la dernière méthode mentionnée par Taz.
 
Merci à tous :jap:

Message cité 1 fois
Message édité par ngkreator le 29-11-2007 à 09:42:24
Reply

Marsh Posté le 29-11-2007 à 10:17:22    

compilateur_C a écrit :

la solution:
- fait leur depart à une zone de memoire qui vous connait leur adresse  
et puis fait l'alocation memoire a l'aide du fonction realoc qui vous permet d'aloce d'une facon contigue et apres que vous continue de la boucle for regarde l'adresse de dernier element insere.


 
Incompréhensible. [:psychokwak]

Reply

Marsh Posté le 29-11-2007 à 10:18:47    

ngkreator a écrit :

Passer la taille en argument je trouve ça moins "élégant" et moins pratique pour l'utilisation de la fonctiona après.


 
Pour moi les deux solutions reviennent peu ou prou au même. [:dawa]

Reply

Marsh Posté le 29-11-2007 à 11:55:58    

Elmoricq a écrit :


 
Pour moi les deux solutions reviennent peu ou prou au même. [:dawa]


 
Ben dans un cas j'appelle la fonction de cette manière:
 

Code :
  1. fonction(p1,p2)


 
Dans l'autre:
 

Code :
  1. fonction(p1,n1,p2,n2)

Reply

Marsh Posté le 29-11-2007 à 11:55:58   

Reply

Marsh Posté le 03-12-2007 à 23:09:04    

ngkreator a écrit :


 
Ben dans un cas j'appelle la fonction de cette manière:
 

Code :
  1. fonction(p1,p2)


 
Dans l'autre:
 

Code :
  1. fonction(p1,n1,p2,n2)



Tu peux aussi lier le pointeur et la taille dans une structure :  

Code :
  1. struct data
  2. {
  3.    T *p;
  4.    size_t n;
  5. };


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-12-2007 à 23:23:19    

pour moi, passer la taille en argument est bien plus élégant.
 
ça permet de pré-dimentionner des collections temporaires (ou pas), sans avoir a parcourir une première fois la collection terminée par un NULL.

Reply

Marsh Posté le 04-12-2007 à 00:38:52    

Emmanuel Delahaye a écrit :


Tu peux aussi lier le pointeur et la taille dans une structure :  

Code :
  1. struct data
  2. {
  3.    T *p;
  4.    size_t n;
  5. };


Oui bien sûr c'est une des 2 solution que je proposais dans mon 1er post :jap:  
 

bjone a écrit :

pour moi, passer la taille en argument est bien plus élégant.
 
ça permet de pré-dimentionner des collections temporaires (ou pas), sans avoir a parcourir une première fois la collection terminée par un NULL.

En fait c'est une question de goût alors j'imagine.

Reply

Marsh Posté le 04-12-2007 à 10:33:33    

bin oui & non.  
 
De manière générale si tu conçois tout un ensemble de routines avec la technique du NULL en fin, tu est souvent obligé de tout parcourir pour rien dans chaque routine ayant une dépendance à la taille avant le traitement.
 
de manière plus générale, je peux te dire que lorsque tu dois retoucher le code d'une appli dont le développeur a le syndrome du "je ne rien conserve rien comme information sur la topologie de mes données et donc je refais plusieures fois les mêmes tests et de préférence par copier/coller", ça donne des envies de meurtre.

Reply

Marsh Posté le 04-12-2007 à 10:35:18    

ngkreator a écrit :

En fait c'est une question de goût alors j'imagine.


Non. C'est surtout une question d'efficacité. Le fait de connaitre la taille, voire la longueur permet de gérer les objets en adresse, longueur, ce qui est beaucoup plus rapide (pas de parcours incessants pour trouver la sentinelle). L'efficacité des chaines 'Pascal' vs 'C' n'est plus à démontrer. C'est ce principe que j'utilise dans mon objet 'FSTR' (Flexible STRing) :  
 
http://mapage.noos.fr/emdel/clib.htm
 
Je ne serais pas étonné que les 'string' du C++ suivent la même voie...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-12-2007 à 11:53:22    

Emmanuel Delahaye a écrit :


Je ne serais pas étonné que les 'string' du C++ suivent la même voie...


 
C'est exactement ça avec la différence qu'on gére la taille de la string courante ET la taille de la zone mémoire qui la contient de manière simultané pour éviter des realloc ttes les 2-3 concatenations.

Reply

Marsh Posté le 04-12-2007 à 12:04:05    

Joel F a écrit :

C'est exactement ça avec la différence qu'on gére la taille de la string courante ET la taille de la zone mémoire qui la contient de manière simultané pour éviter des realloc ttes les 2-3 concatenations.


Héhé :  
 
Tiré de http://delahaye.emmanuel.free.fr/clib/ed/src/fstr.c :

Code :
  1. /* private structures ================================================== */
  2. struct fstr
  3. {
  4.    size_t size; /* size of the array of char */
  5.    size_t w;   /* write index (the postion of the current 0 */
  6.    char *s;   /* pointer to the dynamic array of char */
  7. };



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-12-2007 à 12:06:53    

j'avais pas zieuté ton code mais je m'en doutait un peu [:dawa]


Message édité par Joel F le 04-12-2007 à 12:07:00
Reply

Marsh Posté le 04-12-2007 à 14:05:35    

bjone a écrit :

bin oui & non.  
 
De manière générale si tu conçois tout un ensemble de routines avec la technique du NULL en fin, tu est souvent obligé de tout parcourir pour rien dans chaque routine ayant une dépendance à la taille avant le traitement.
 
de manière plus générale, je peux te dire que lorsque tu dois retoucher le code d'une appli dont le développeur a le syndrome du "je ne rien conserve rien comme information sur la topologie de mes données et donc je refais plusieures fois les mêmes tests et de préférence par copier/coller", ça donne des envies de meurtre.


J'avais pas vu de ce coté là :D Vous m'avez convaincu.
 
Sinon sympa les librairies d'ED.

Reply

Sujets relatifs:

Leave a Replay

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