fonction saisie ligne sans limite - C - Programmation
Marsh Posté le 18-12-2007 à 22:48:56
Tu devrais éviter de faire un realloc() à chaque char, c'est très pénalisant. Fait plutôt tes reallocs() par blocs : quand tu n'as plus de place dans le buffer tu lui ajoutes un bloc de 4096 octets par exemple, et ensuite tu es tranquile pour 4096 getchar().
Ensuite une fois que tu realloc() par bloc, tu peux aussi faire les lectures par blocs avec fgets(). Ca t'évitera autant d'appels de fonction.
Enfin, si ton système dispose de getline(), c'est exactement ce que tu veux.
Marsh Posté le 19-12-2007 à 08:24:39
On peut commencer par 4096 et il est conseillé pour la reallocation de multiplier la taille par le nombre d'or.
Marsh Posté le 19-12-2007 à 10:13:16
La fonction que j'avais créée à cette fin, je l'utilisais pour lire des fichiers de données, et donc plutôt que de refaire à chaque ligne lue les mêmes phases de réallocations, je stockais la taille du bloc dans un static.
La taille initiale était assez petite (dans les 100-200 je crois), à chaque réallocation je doublais, et je stockais la nouvelle taille. Comme ça, à chaque allocation j'allouais le plus gros bloc déjà alloué auparavant, le but étant de minimiser le nombre de realloc() lors de la lecture de nombreuses lignes de tailles similaires.
Marsh Posté le 19-12-2007 à 10:37:48
Bonjour,
Code :
|
Il y a une fuite de mémoire si 'realloc' échoue, il me semble...
Extrait du man :
|
Marsh Posté le 19-12-2007 à 10:41:09
Trap D a écrit : On peut commencer par 4096 et il est conseillé pour la reallocation de multiplier la taille par le nombre d'or. |
Seulement les jours de pleine lune
Marsh Posté le 19-12-2007 à 10:48:37
spotaszn a écrit : Il y a une fuite de mémoire si 'realloc' échoue, il me semble... |
Il te semble bien.
Pour correctement utiliser realloc(), si l'on souhaite poursuivre le programme après échec, il faut effectivement passer par une variable temporaire, ce qui laisse le pointeur initialement utilisé intact.
Marsh Posté le 19-12-2007 à 13:04:42
Merci pour toutes vos réponses!
Marsh Posté le 19-12-2007 à 14:32:43
matafan a écrit : |
Plutôt avec un allocateur best fit. Mais osef, on parle de quelques octets. 4096 c'est peut être excessif cependant comme départ.
Marsh Posté le 19-12-2007 à 14:33:32
ngkreator a écrit : Merci pour toutes vos réponses!
|
y a getline en C mais pas standard, extension GNU.
Marsh Posté le 19-12-2007 à 14:44:57
Ah oui donc je vais rester sur du standard.
Code :
|
Porblème:
Code :
|
Si le bloc mémoire pointé par strIn est déplacé (lors de la réallocation) de l'emplacement mémoire A vers B on pourrait libérer A. Mais on ne sais pas quand il y a eu déplacement ou non. On ne peut donc pas faire:
Code :
|
Au grand risque de libérer A alors que strTmp pointe également vers A.
Comment faire?
Il faut aussi que je gère la vidange du stdin avant de commencer d'ailleurs.
Marsh Posté le 20-12-2007 à 01:27:07
Attention, le realloc "libère" de lui-même (ou plutôt remet à disposition dans la heap) la mémoire originelle du pointeur si la ré-allocation c'est bien passé. D'ailleurs dans le cas présent, il ne faut surtout pas essayer de faire un free sur le strIn, qui pointe vers l'ancienne zone mémoire (voir pire la même) et cela fera ce que l'on appelle de la memory corruption.
donc pour moi ton code initial est bon et ne comporte pas de fuite.
Par contre, pour la beauté du geste, je n'aime pas écrire 2 fois le même code,comme la ligne suivante qui y est 2 fois :
Code :
|
en réflechissant un peu, tu verras qu'il est possible de d'abord mettre le caractère dans le tableau, faire le ++ et ensuite (avec la bonne condition, une simple égalité) faire si nécessaire l'augmentation de la taille du buffer...
Le if initial est inutile, surtout si tu réordonance un peu la condition dans le while (si ton souhait est d'éviter un getchar dont tu ne ferais rien)
D'ailleurs, la politique du *=2 me parrait un peu violente, mais c'est un choix
Mais tout cela n'est que détail
Au final je verais qqch du style
Code :
|
Bon courage
Marsh Posté le 18-12-2007 à 21:46:03
Bonjour, j'essaie de faire une fonction qui me permette de récupérer une ligne entrée au clavier sans le '\n' final.
Mon but est de faire une fonction qui n'ai pas besoin de limite dans la taille de la ligne à saisir. J'ai donc pensé à realloc, je trouve ça bourrin, mais ça marche:
Je compte l'utiliser souvent donc j'aimerais bien avoir des retours SVP, merci d'avance.
Message édité par ngkreator le 18-12-2007 à 21:48:53