passage d'un buffer comme parametre - C - Programmation
Marsh Posté le 25-11-2005 à 05:20:37
Il faut soit que ta fonction loadFile prennent en argument un char ** et que tu l'appelles avec loadFile(nom_fichier, &contenu_fichier), soit qu'elle retourne le char * (je ferais plutôt comme ça). Parce que dans ton code, loadFile ne met pas contenu_fichier à jour dans l'appelant.
Marsh Posté le 25-11-2005 à 05:21:23
carabin a écrit : J'ai un souci pour passer un buffer comme parametre d'une fonction. |
Hum... si tu parles de la fonction "loadfile" moi je la vois renvoyer un "int" avec ce commentaire "Tout s'est bien passé".
Et pour moi, un "int" n'est pas une adresse !!!
carabin a écrit : Apparement l'adresse n'est pas renvoyée correctement, mais je ne vois pas pourquoi. |
Cf remarque ci-dessus. Je rajouterai que si ta fonction "loadfile" est sensée renvoyer une adresse, il serait bien de récupérer cette adresse dans le main avec une instruction du style "var=loadfile(...)".
Maintenant, pourquoi ton "main" passe la variable "contenu_fichier" à la fonction "loadfile" vu que la fonction est sensée créer la zone (malloc) et renvoyer la zone créée ? Elle n'utilise pas la valeur qu'elle reçoit du main puisqu'elle l'écrase d'entrée avec un malloc !!!
carabin a écrit : Je comprends parfaitement les notions de pointeur, par contre je me mélange un peu avec la notation (suis pas toujours très sur quand il faut mettre juste le nom, ou y rajouter un * ou un &, je sais qui fait quoi, mais ca ne m'empeche pas de me melanger les pinceaux). |
C'est parce que tu ne visualises pas réellement le type de ce qui est attendu par les fonctions que tu vas utiliser !!!
Quand tu déclares "char *pt", tu déclares une variable nommée "pt" de type "char étoile". Et accessoirement, la valeur "*pt" (ce qu'il y a au bout de "pt" ) est de type "char" (avec un dessin ce serait plus parlant).
Maintenant, tu as une fonction "void f(int *pt)". La fonction attend un paramètre de type "int étoile". Il faut donc lui passer un paramètre de type "int étoile". Tu remarqueras que si je prends la peine d'écrire le mot "étoile", c'est que ce mot est important. Une variable de type "int" n'est pas de type "int étoile". Et une variable de type "int étoile" n'est pas de type "int étoile étoile". Chaque étoile a son importance...
Donc tu dois lui passer un paramètre de type "int étoile". Et tu as, dans la fonction appelante, une variable "int *toto". Là, le débutant se dit "ma fonction attend un int étoile, je lui passe "*toto" => f(*toto)
Eh bien c'est faux ! "*toto" est de type "int" et ce n'est pas ce que la fonction attend
Dans "int *toto" quelle est la variable de type "int étoile" ? Eh bien c'est "toto". Tu appelles "f(toto)" et la fonction "f" reçoit bien un "int étoile"
Autre cas: tu as maintenant un paramètre de type "int titi". Et tu veux appeler "f". Il faut encore lui passer un "int étoile". Eh bien on peut utiliser le truc suivant:
Donc on passe "&titi" à la fonction... qui reçoit bien un "int étoile"
Exemple illustratif
Code :
|
Marsh Posté le 25-11-2005 à 09:15:34
carabin a écrit : J'ai un souci pour passer un buffer comme parametre d'une fonction. |
C'est quoi un 'buffer' ? Tu veux dire un tableau ?
http://mapage.noos.fr/emdel/notes.htm#param_tab
Maintenant, si tu crées un tableau dynamiquement dans une fonction, tu dois retourner son adresse. Soit par return
pseudocode
|
soit
pseudocode
|
Marsh Posté le 25-11-2005 à 09:24:14
Emmanuel Delahaye a écrit :
|
Et en l'utilisant de cette façon :
pseudocode
|
Emmanuel Delahaye a écrit : soit
|
Et en l'utilisant de cette façon :
pseudocode
|
Marsh Posté le 25-11-2005 à 23:42:33
Tout dabord, merci a tous pour vos réponses. Après avoir posté, j'ai passé encore au moins une heure à chercher mon erreur, puis j'en ai eu marre, ai eteint le Pc et suit allé me coucher ---> et c'est à ce moment la que j'ai compris le problème. Moralité, il faut de temps en temps décoller le nez de son écran !!!
Ce que j'ai fait ne me permets que de modidier le contenu de buffer, par contre pour renvoyer son adresse a main, il me manquait betement un niveau de pointeur. Donc il fallait que je mette un pointeur SUR le pointeur SUR buffer pour modifier/attribuer l'adresse donnée par malloc (--> comme le disait donc matafan )
En fait, la ou je m'embrouille generalement avec les pointeurs, c'est lors d'un passage de parametres. Le fait de devoir rajouter un niveau d'indirection à le don de me foutre dedans !
Emannuel --> oui, buffer = tableau
Sve@r --> desolé, je n'ai peut etre pas ete super clair dans mes propos. Je ne cherche pas à renvoyer l'adresse par le return, mais par les arguments. Le return me sert pour faire un test au retour de la fonction (même si je ne l'utilise pas encore) , pour savoir si tout s'est bien passé. Le but de la manoeuvre, c'est que main envoit un pointeur non attribué "contenu_fichier" (que j'ai d'ailleurs oublié de mettre à NULL) à la fonction, et que la fonction modifie ce pointeur pour qu'il adresse la zone attribuée par malloc. Ce qui ferais qu'avant l'appel de la fonction, "contenu_fichier" ne pointe sur rien, et qu'au retour, elle pointe sur la fameuse zone mémoire créé dans la fonction (avec le contenu du fichier, oeuf corse).
En fait ce que je cherchais à faire est la même chose que dans le deuxième exemple donné par Emmanuel et complete par Sve@r. D'ailleurs, merci pour ce bout de code, auquel j'ai put comparer ma correction et voir qu'elle etait bonne. Par contre, je vois que j'ai aussi oublié de tester le retour de mon malloc !
Et pis surtout, même si j'apprécie votre aide, je suis super content d'avoir réussi à comprendre par moi-même (suis pas si con en fin de compte )
Ci dessous mon code corrigé (qui marche enfin comme je le souhaite )
HS : Sve@r, il faut le prononcer comment ? Sveor, Svear, SveATr ? autre ?
Code :
|
Marsh Posté le 26-11-2005 à 10:01:44
carabin a écrit : Sve@r --> desolé, je n'ai peut etre pas ete super clair dans mes propos. Je ne cherche pas à renvoyer l'adresse par le return, mais par les arguments. |
Exact, t'étais pas super clair et même là tes propos sont encore flous. On ne peut renvoyer de valeur que par un "return". On ne renvoie pas de valeur par les arguments.
Ce que tu cherchais à faire, c'est modifier une variable de la fonction appelante dans la fonction appelée. Dans ce cas, le seul moyen est de passer l'adresse de cette variable à la fonction appelée. Et quand la variable est de type "<type>", la fonction reçoit un "<type> étoile". Dans ton cas, la variable étant de type "char étoile", la fonction reçoit un "char étoile étoile"
carabin a écrit : En fait ce que je cherchais à faire est la même chose que dans le deuxième exemple donné par Emmanuel et complete par Sve@r. |
C'est un cas d'école
carabin a écrit : Et pis surtout, même si j'apprécie votre aide, je suis super content d'avoir réussi à comprendre par moi-même |
C'est le plus important - Les choses qu'on arrive à comprendre tout seul sont celles qui restent...
carabin a écrit : HS : Sve@r, il faut le prononcer comment ? Sveor, Svear, SveATr ? autre ? |
J'en n'ai aucune idée. Il me fallait un pseudo et je me suis souvenu des aventures de Thorgal. A un moment, il rencontre "Darek le Svear" aux alentours de l'album "la forteresse invisible". Et voilà mon pseudo. Sur DoD quand on joue en équipe avec la voix, les gars de ma team prononcent à l'américaine "Sveire"...
Marsh Posté le 26-11-2005 à 11:02:43
carabin a écrit : Tout dabord, merci a tous pour vos réponses. Après avoir posté, j'ai passé encore au moins une heure à chercher mon erreur, puis j'en ai eu marre, ai eteint le Pc et suit allé me coucher ---> et c'est à ce moment la que j'ai compris le problème. Moralité, il faut de temps en temps décoller le nez de son écran !!! |
Exact. Je ne compte plus les solutions trouvées au lit, en voiture ou sur le trone...
Citation : |
C'est le but !
Marsh Posté le 24-11-2005 à 23:47:59
J'ai un souci pour passer un buffer comme parametre d'une fonction.
Le but de la fonction est d'ouvrir un fichier, de creer un buffer de taille adaptée, d'y copier le contenu du fichier, de fermer le fichier, et de retourner l'adresse de ce buffer.
Jusqu'a présent, je faisait ca sans probleme directement dans le main. La, j'ai voulu en faire une fonction, pour reutiliser plus facilement, mais ca ne marche pas.
La messagebox dans la fonction me donne l'affichage correct du contenu du fichier test.txt, par contre la messagebox dans main indique n'importe quoi, et ca plante si on écrit dans le buffer contenu_fichier.
Apparement l'adresse n'est pas renvoyée correctement, mais je ne voiss pas pourquoi. Je comprends parfaitement les notions de pointeur, par contre je me mélange un peu avec la notation (suis pas toujours très sur quand il faut mettre juste le nom, ou y rajouter un * ou un &, je sais qui fait quoi, mais ca ne m'empeche pas de me melanger les pinceaux).
A coup sur, il y a une erreur évidente qui devrait me crever les yeux, mais rien n'y fait, je ne la voit pas. Si quelqu'un pouvait m'eclairer !
Merci d'avance.
-> (win98SE, devcpp 4.9.9.0 )
note au modos : dsl si jamais le message apparait deux fois, mais le premier coup je l'ai pas vu apparaiter dans la liste.