Est-on assur=E9 que les =E9l=E9ments d'un std::vector se suivent en m=E9moi=
re?
Je veux utiliser un vector pour me d=E9charger de l'allocation dynamique
t'un tableau temporaire de caract=E8res.
Ca marche sous VC++ 2003.
Mais est-ce standard et/ou portable?
J'ai aussi essay=E9 ceci, mais =E7a ne marche pas dans tous les cas et
=E9clanche parfois des exceptions. Je soupsonne l'impl=E9mentation de ne
pas vraiment effectuer le reserve().
Rq: je ne peux pas me permettre d'utiliser les iostreams pour des
raisons de performance. La fonction parser doit interpr=E9ter des
fichiers de plusieurs centaines de ko de texte.
Est-on assuré que les éléments d'un std::vector se suivent en mémoire?
Oui.
Depuis assez récemment, c'est garanti par la norme. Avant, c'était à peu près garanti aussi, car il était impossible d'implémenter std::vector<> autrement.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas
[...] const_cast [...]
Faut pas chercher plus loin la source du problème...
Et je confirme que dans ton cas, c'est std::vector<char> qu'il faut utiliser.
On 17 Mar 2007 11:44:23 -0700, "hyronn@gmail.com" <hyronn@gmail.com>:
Est-on assuré que les éléments d'un std::vector se suivent en mémoire?
Oui.
Depuis assez récemment, c'est garanti par la norme.
Avant, c'était à peu près garanti aussi, car il était impossible
d'implémenter std::vector<> autrement.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas
[...] const_cast [...]
Faut pas chercher plus loin la source du problème...
Et je confirme que dans ton cas, c'est std::vector<char> qu'il faut
utiliser.
Est-on assuré que les éléments d'un std::vector se suivent en mémoire?
Oui.
Depuis assez récemment, c'est garanti par la norme. Avant, c'était à peu près garanti aussi, car il était impossible d'implémenter std::vector<> autrement.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas
[...] const_cast [...]
Faut pas chercher plus loin la source du problème...
Et je confirme que dans ton cas, c'est std::vector<char> qu'il faut utiliser.
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il faut remplacer le reserve par resize. Avec le problème que dans ce cas, on initialise forcément la zone mémoire en question, pour rien.
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il
faut remplacer le reserve par resize. Avec le problème que dans ce cas,
on initialise forcément la zone mémoire en question, pour rien.
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il faut remplacer le reserve par resize. Avec le problème que dans ce cas, on initialise forcément la zone mémoire en question, pour rien.
-- Loïc
Mathias Gaunard
Bonsoir,
Est-on assuré que les éléments d'un std::vector se suivent en mémoire? Je veux utiliser un vector pour me décharger de l'allocation dynamique t'un tableau temporaire de caractères.
1) le cast est inutile. Les casts étant une chose dangereuse à éviter (particulièrement les casts C), si en plus c'est inutile, c'est quand même con d'en mettre.
2) std::vector ne garantit rien pour l'accès à la mémoire réservée. Il te faut des vrais objets. Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement utiliser le constructeur
3) FILENAME_MAX est probablement une constante fixe du préprocesseur. Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ?
4) Ta fonction ne fait rien d'utile avec str.
Bonsoir,
Est-on assuré que les éléments d'un std::vector se suivent en mémoire?
Je veux utiliser un vector pour me décharger de l'allocation dynamique
t'un tableau temporaire de caractères.
1) le cast est inutile. Les casts étant une chose dangereuse à éviter
(particulièrement les casts C), si en plus c'est inutile, c'est quand
même con d'en mettre.
2) std::vector ne garantit rien pour l'accès à la mémoire réservée.
Il te faut des vrais objets.
Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement
utiliser le constructeur
3) FILENAME_MAX est probablement une constante fixe du préprocesseur.
Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ?
Est-on assuré que les éléments d'un std::vector se suivent en mémoire? Je veux utiliser un vector pour me décharger de l'allocation dynamique t'un tableau temporaire de caractères.
1) le cast est inutile. Les casts étant une chose dangereuse à éviter (particulièrement les casts C), si en plus c'est inutile, c'est quand même con d'en mettre.
2) std::vector ne garantit rien pour l'accès à la mémoire réservée. Il te faut des vrais objets. Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement utiliser le constructeur
3) FILENAME_MAX est probablement une constante fixe du préprocesseur. Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ?
4) Ta fonction ne fait rien d'utile avec str.
Mathias Gaunard
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments sont passés ici par valeur.
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments sont
passés ici par valeur.
Ah oui, et le second const est sans intérêt, puisque les arguments sont passés ici par valeur.
hyronn
2) std::vector ne garantit rien pour l'accès à la mémoire réserv ée. Il te faut des vrais objets. Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement utiliser le constructeur ok
3) FILENAME_MAX est probablement une constante fixe du préprocesseur. Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ? Je m'attendais à ce que FILENAME_MAX (de <cstdio>) soit plus grand que
la pile. Un pile usuelle fait dans les 8k et MAX_PATH (constante windowsienne similaire) fait 32k Je craignais un stack overflow. Mais sur mon implementation (VC++2003) FILENAME_MAX = 260 Donc la pile fera l'affaire. Mais question portabilité, c bof.. Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur vos implémentation ;-) Merci
4) Ta fonction ne fait rien d'utile avec str. C'était un exemple.
2) std::vector ne garantit rien pour l'accès à la mémoire réserv ée.
Il te faut des vrais objets.
Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement
utiliser le constructeur
ok
3) FILENAME_MAX est probablement une constante fixe du préprocesseur.
Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ?
Je m'attendais à ce que FILENAME_MAX (de <cstdio>) soit plus grand que
la pile.
Un pile usuelle fait dans les 8k et MAX_PATH (constante windowsienne
similaire) fait 32k
Je craignais un stack overflow.
Mais sur mon implementation (VC++2003) FILENAME_MAX = 260
Donc la pile fera l'affaire.
Mais question portabilité, c bof..
Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur
vos implémentation ;-) Merci
4) Ta fonction ne fait rien d'utile avec str.
C'était un exemple.
2) std::vector ne garantit rien pour l'accès à la mémoire réserv ée. Il te faut des vrais objets. Donc n'utilise pas reserve mais resize. Ici, on peut tout simplement utiliser le constructeur ok
3) FILENAME_MAX est probablement une constante fixe du préprocesseur. Par conséquent, pourquoi ne pas utiliser un tableau normal sur la pile ? Je m'attendais à ce que FILENAME_MAX (de <cstdio>) soit plus grand que
la pile. Un pile usuelle fait dans les 8k et MAX_PATH (constante windowsienne similaire) fait 32k Je craignais un stack overflow. Mais sur mon implementation (VC++2003) FILENAME_MAX = 260 Donc la pile fera l'affaire. Mais question portabilité, c bof.. Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur vos implémentation ;-) Merci
4) Ta fonction ne fait rien d'utile avec str. C'était un exemple.
hyronn
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments so nt passés ici par valeur.
Je ne comprend pas. J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il puisse effectuer une optimisation dont je n'ai peut être pas connaissance. Quel est le pb? Merci
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments so nt
passés ici par valeur.
Je ne comprend pas.
J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il
puisse effectuer une optimisation dont je n'ai peut être pas
connaissance.
Quel est le pb?
Merci
Ah oui, et le second const est sans intérêt, puisque les arguments so nt passés ici par valeur.
Je ne comprend pas. J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il puisse effectuer une optimisation dont je n'ai peut être pas connaissance. Quel est le pb? Merci
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il faut remplacer le reserve par resize. Avec le problème que dans ce cas, on initialise forcément la zone mémoire en question, pour rien.
Juste par chance en fait! Reserve() ou le constructeur a bien alloué de la mémoire. J'écris sur cette emplacement, sans invoquer les procédures du vector, il est donc normal que size() == 0.
Je suis conscient du gaspillage de mémoire. L'ordre de grandeur est de 33k, ce qui est convenable au vu de mon "cahier des charges".
On 17 mar, 21:39, Loïc Joly <loic.actarus.j...@numericable.fr> wrote:
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il
faut remplacer le reserve par resize. Avec le problème que dans ce cas,
on initialise forcément la zone mémoire en question, pour rien.
Juste par chance en fait!
Reserve() ou le constructeur a bien alloué de la mémoire.
J'écris sur cette emplacement, sans invoquer les procédures du
vector,
il est donc normal que size() == 0.
Je suis conscient du gaspillage de mémoire. L'ordre de grandeur est de
33k, ce qui est convenable au vu de mon "cahier des charges".
J'en suis bien surpris... Après ce code, str.size() vaut encore 0. Il faut remplacer le reserve par resize. Avec le problème que dans ce cas, on initialise forcément la zone mémoire en question, pour rien.
Juste par chance en fait! Reserve() ou le constructeur a bien alloué de la mémoire. J'écris sur cette emplacement, sans invoquer les procédures du vector, il est donc normal que size() == 0.
Je suis conscient du gaspillage de mémoire. L'ordre de grandeur est de 33k, ce qui est convenable au vu de mon "cahier des charges".
James Kanze
On Mar 17, 7:44 pm, "" wrote:
Est-on assuré que les éléments d'un std::vector se suivent en mém oire? Je veux utiliser un vector pour me décharger de l'allocation dynamique t'un tableau temporaire de caractères.
Ça ne marche pas du tout. Reserve() ne change pas la taille du vecteur. Ce qu'il te faut, c'est resize(), non réserve.
Mais est-ce standard et/ou portable?
Avec resize(), oui. Et tu n'as pas besoin du cast pour le dernier parametre.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas et éclanche parfois des exceptions. Je soupsonne l'implémentation de ne pas vraiment effectuer le reserve().
La norme n'exige pas que reserve() fasse quoique ce soit dans le cas de std::string. Elle n'exige pas (encore) non plus que le pointeur renvoyé par data() correspond au contenu de la chaîne. Dans la pratique, si tu utilises resize() à la place de reserve(), ça doit marcher avec toutes les implémentations existantes. Il y a une proposition devant le comité (acceptée en principe, je crois) pour exiger la contiguïté du buffer dans basic_string aussi, et de fournir une version non-const de data().
Rq: je ne peux pas me permettre d'utiliser les iostreams pour des raisons de performance. La fonction parser doit interpréter des fichiers de plusieurs centaines de ko de texte.
Et qu'est-ce qui te dit que sscanf soit plus performant ? Ça doit dépendre beaucoup de l'implémentation.
Si c'est vraiment une question de performance, strchr, etc. sur la chaîne initiale est probablement ce qui serait la plus rapide. Ensuite, la construction des chaînes dont tu as besoin à partir des pointeurs trouvés.
-- James Kanze (Gabi Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Mar 17, 7:44 pm, "hyr...@gmail.com" <hyr...@gmail.com> wrote:
Est-on assuré que les éléments d'un std::vector se suivent en mém oire?
Je veux utiliser un vector pour me décharger de l'allocation dynamique
t'un tableau temporaire de caractères.
Ça ne marche pas du tout. Reserve() ne change pas la taille du
vecteur. Ce qu'il te faut, c'est resize(), non réserve.
Mais est-ce standard et/ou portable?
Avec resize(), oui. Et tu n'as pas besoin du cast pour le
dernier parametre.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas et
éclanche parfois des exceptions. Je soupsonne l'implémentation de ne
pas vraiment effectuer le reserve().
La norme n'exige pas que reserve() fasse quoique ce soit dans le
cas de std::string. Elle n'exige pas (encore) non plus que le
pointeur renvoyé par data() correspond au contenu de la chaîne.
Dans la pratique, si tu utilises resize() à la place de
reserve(), ça doit marcher avec toutes les implémentations
existantes. Il y a une proposition devant le comité (acceptée en
principe, je crois) pour exiger la contiguïté du buffer dans
basic_string aussi, et de fournir une version non-const de
data().
Rq: je ne peux pas me permettre d'utiliser les iostreams pour des
raisons de performance. La fonction parser doit interpréter des
fichiers de plusieurs centaines de ko de texte.
Et qu'est-ce qui te dit que sscanf soit plus performant ? Ça
doit dépendre beaucoup de l'implémentation.
Si c'est vraiment une question de performance, strchr, etc. sur
la chaîne initiale est probablement ce qui serait la plus
rapide. Ensuite, la construction des chaînes dont tu as besoin
à partir des pointeurs trouvés.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Est-on assuré que les éléments d'un std::vector se suivent en mém oire? Je veux utiliser un vector pour me décharger de l'allocation dynamique t'un tableau temporaire de caractères.
Ça ne marche pas du tout. Reserve() ne change pas la taille du vecteur. Ce qu'il te faut, c'est resize(), non réserve.
Mais est-ce standard et/ou portable?
Avec resize(), oui. Et tu n'as pas besoin du cast pour le dernier parametre.
J'ai aussi essayé ceci, mais ça ne marche pas dans tous les cas et éclanche parfois des exceptions. Je soupsonne l'implémentation de ne pas vraiment effectuer le reserve().
La norme n'exige pas que reserve() fasse quoique ce soit dans le cas de std::string. Elle n'exige pas (encore) non plus que le pointeur renvoyé par data() correspond au contenu de la chaîne. Dans la pratique, si tu utilises resize() à la place de reserve(), ça doit marcher avec toutes les implémentations existantes. Il y a une proposition devant le comité (acceptée en principe, je crois) pour exiger la contiguïté du buffer dans basic_string aussi, et de fournir une version non-const de data().
Rq: je ne peux pas me permettre d'utiliser les iostreams pour des raisons de performance. La fonction parser doit interpréter des fichiers de plusieurs centaines de ko de texte.
Et qu'est-ce qui te dit que sscanf soit plus performant ? Ça doit dépendre beaucoup de l'implémentation.
Si c'est vraiment une question de performance, strchr, etc. sur la chaîne initiale est probablement ce qui serait la plus rapide. Ensuite, la construction des chaînes dont tu as besoin à partir des pointeurs trouvés.
-- James Kanze (Gabi Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze
On Mar 18, 9:54 am, "" wrote:
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments sont passés ici par valeur.
Je ne comprend pas. J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il puisse effectuer une optimisation dont je n'ai peut être pas connaissance. Quel est le pb?
Aucun problème, mais il apporte en fait assez peu, vue qu'il ne conditionne qu'une variable locale, dont tous les accès sont visibles, et par le compilateur, et par le lecteur.
Son utilisation est, à mon avis, une question de style. La déclaration de la fonction (que voit les autres utilisateurs) ne doit pas le comporter -- là, il ne signifie rien. Alors, certains préfère que les paramètres dans la définition s'écrivent de façon exactement identiques à ceux de la déclaration, quitte à rénouncer à l'avantage d'une const locale. D'autres préfère les avantages du const, même au prix que la déclaration et la définition apparaissent légèrement différentes.
Personnellement, je n'utilise pas le const dans ce cas-ci, mais comme j'ai dit, c'est vraiment une question de style, et je ne rejetterais certainement pas du code dans une revue de code pour cette raison. Si tu te sens plus à l'aise avec le const, il n'y a aucune raison de changer.
-- James Kanze (Gabi Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Mar 18, 9:54 am, "hyr...@gmail.com" <hyr...@gmail.com> wrote:
void parse1(const char* const txt_buffer)
Ah oui, et le second const est sans intérêt, puisque les arguments sont
passés ici par valeur.
Je ne comprend pas.
J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il
puisse effectuer une optimisation dont je n'ai peut être pas
connaissance.
Quel est le pb?
Aucun problème, mais il apporte en fait assez peu, vue qu'il ne
conditionne qu'une variable locale, dont tous les accès sont
visibles, et par le compilateur, et par le lecteur.
Son utilisation est, à mon avis, une question de style. La
déclaration de la fonction (que voit les autres utilisateurs) ne
doit pas le comporter -- là, il ne signifie rien. Alors,
certains préfère que les paramètres dans la définition
s'écrivent de façon exactement identiques à ceux de la
déclaration, quitte à rénouncer à l'avantage d'une const locale.
D'autres préfère les avantages du const, même au prix que la
déclaration et la définition apparaissent légèrement
différentes.
Personnellement, je n'utilise pas le const dans ce cas-ci, mais
comme j'ai dit, c'est vraiment une question de style, et je ne
rejetterais certainement pas du code dans une revue de code pour
cette raison. Si tu te sens plus à l'aise avec le const, il n'y
a aucune raison de changer.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Ah oui, et le second const est sans intérêt, puisque les arguments sont passés ici par valeur.
Je ne comprend pas. J'indique au compilateur que txt_buffer ne sera pas modifié afin qu'il puisse effectuer une optimisation dont je n'ai peut être pas connaissance. Quel est le pb?
Aucun problème, mais il apporte en fait assez peu, vue qu'il ne conditionne qu'une variable locale, dont tous les accès sont visibles, et par le compilateur, et par le lecteur.
Son utilisation est, à mon avis, une question de style. La déclaration de la fonction (que voit les autres utilisateurs) ne doit pas le comporter -- là, il ne signifie rien. Alors, certains préfère que les paramètres dans la définition s'écrivent de façon exactement identiques à ceux de la déclaration, quitte à rénouncer à l'avantage d'une const locale. D'autres préfère les avantages du const, même au prix que la déclaration et la définition apparaissent légèrement différentes.
Personnellement, je n'utilise pas le const dans ce cas-ci, mais comme j'ai dit, c'est vraiment une question de style, et je ne rejetterais certainement pas du code dans une revue de code pour cette raison. Si tu te sens plus à l'aise avec le const, il n'y a aucune raison de changer.
-- James Kanze (Gabi Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mathias Gaunard
Un pile usuelle fait dans les 8k
Une pile usuelle de 1980 ? Un compilateur pourrait a priori détecter, modulo l'usage de la récursivité, de quelle taille la pile doit être et t'avertir dans le cas où la pile nécessaire serait trop grande.
et MAX_PATH (constante windowsienne similaire) fait 32k
Un chemin et un nom de fichier c'est pas exactement la même chose.
Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur vos implémentation ;-)
Le plus long nom possible que j'ai trouvé en regardant les caractéristiques des systèmes de fichiers c'est 4032 octets.
Mais 255 est quand même une valeur récurrente.
Un pile usuelle fait dans les 8k
Une pile usuelle de 1980 ?
Un compilateur pourrait a priori détecter, modulo l'usage de la
récursivité, de quelle taille la pile doit être et t'avertir dans le cas
où la pile nécessaire serait trop grande.
et MAX_PATH (constante windowsienne
similaire) fait 32k
Un chemin et un nom de fichier c'est pas exactement la même chose.
Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur
vos implémentation ;-)
Le plus long nom possible que j'ai trouvé en regardant les
caractéristiques des systèmes de fichiers c'est 4032 octets.
Une pile usuelle de 1980 ? Un compilateur pourrait a priori détecter, modulo l'usage de la récursivité, de quelle taille la pile doit être et t'avertir dans le cas où la pile nécessaire serait trop grande.
et MAX_PATH (constante windowsienne similaire) fait 32k
Un chemin et un nom de fichier c'est pas exactement la même chose.
Auriez-vous l'aimabilité de rapporter la valeur de FILENAME_MAX sur vos implémentation ;-)
Le plus long nom possible que j'ai trouvé en regardant les caractéristiques des systèmes de fichiers c'est 4032 octets.