OVH Cloud OVH Cloud

[STL] clear vs resize(0)

11 réponses
Avatar
Amerio
Bonjour,
La fonction clear() d'un std::vector "vide" le conteneur (mise a 0 de la
taille, et destruction des elements contenus).
Mais sur PC (VS 2003), clear() désalloue egalement toute la place réservé
par le vector (si j'avais fais un reserve(100) avant, alors apres le clear
c'est retombé a 0).
Si je remplace clear() par resize(0), alors la mémoire reservée n'est pas
perdue.
Questions :
- le comportement de clear() est il normalisé (vis a vis de reserve() ) ?
- peut il y a voir une impémenattion ou resize(0) fait _exactement_ comme
clear() ?
- y a t il une methode "standard" pour vider un conteneur, sans perdre
l'effet de "reserve()" ?
Merci !

10 réponses

1 2
Avatar
darkman_spam
"Amerio" wrote in message news:<40e3c49c$0$10291$...

- le comportement de clear() est il normalisé


Oui.

(vis a vis de reserve() ) ?


Je ne suis pas certain de comprendre la question. Tout ce que j'ai
trouvé su `clear()' est

Table 67, 23.1.1/4 :

expression | return type | assertion/note
| | pre/post-condition
-------------+--------------+-----------------------
a.clear() | void | erase(begin(), end())
| | post: size() == 0
-------------+--------------+-----------------------

- peut il y a voir une impémenattion ou resize(0) fait _exactement_ comme
clear() ?


23.2.4.2/6 :

void resize(size_type sz, T c = T());

Effects:

if (sz > size())
insert(end(), sz-size(), c);
else if (sz < size())
erase(begin()+sz, end());
else
;

Dans le cas de « resize( 0 ) », il s'agit donc bien du même
comportement. La seule différence éventuelle à trait à `size()'. Je
n'ai en effet pas trouvé dans la norme l'effet de `erase()' sur
celle-ci. Si cet effet est nul, ce que je pense, la post-condition de
`clear()' « size() == 0 » est un effet supplémentaire à « resize( 0 ) ».

- y a t il une methode "standard" pour vider un conteneur, sans perdre
l'effet de "reserve()" ?


D'après ce qui précède, il semblerait que ce que tu veux est
« x.resize( 0 ) » ou son équivalent « x.erase( x.begin() , x.end() ) ».

Détails à confirmer ou infirmer.

--drkm

Avatar
Loïc Joly
Amerio wrote:

Bonjour,
La fonction clear() d'un std::vector "vide" le conteneur (mise a 0 de la
taille, et destruction des elements contenus).
Mais sur PC (VS 2003), clear() désalloue egalement toute la place réservé
par le vector (si j'avais fais un reserve(100) avant, alors apres le clear
c'est retombé a 0).



D'après ma lecture de la norme, ce comportement n'est pas légal (ce que
j'ai lu se trouve dans une note. Est-ce normatif, et sinon où se trouve
ce genre d'info ?).

23.2.4.2 vector capacity
[...]
5 Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is guaranteed
that no reallocation takes place during insertions that happen after a
call to reserve() until the time when an insertion would make the size
of the vector greater than the size specified in the most recent call to
reserve().

--
Loïc

Avatar
Franck Branjonneau
(drkm) écrivait:

Dans le cas de « resize( 0 ) », il s'agit donc bien du même
comportement. La seule différence éventuelle à trait à `size()'. Je
n'ai en effet pas trouvé dans la norme l'effet de `erase()' sur
celle-ci. Si cet effet est nul, ce que je pense, la post-condition de
`clear()' « size() == 0 » est un effet supplémentaire à « resize( 0
) ».


Uh ? clear() implique size() == 0.
--
Franck Branjonneau

Avatar
darkman_spam
Franck Branjonneau wrote in message news:...

drkm écrivait:

Dans le cas de « resize( 0 ) », il s'agit donc bien du même
comportement. La seule différence éventuelle à trait à `size()'. Je
n'ai en effet pas trouvé dans la norme l'effet de `erase()' sur
celle-ci. Si cet effet est nul, ce que je pense, la post-condition de
`clear()' « size() == 0 » est un effet supplémentaire à « resize( 0
) ».


Uh ? clear() implique size() == 0.


Oops. Je me suis emmêlé les size() et capacity().

--drkm


Avatar
drkm
Loïc Joly writes:

23.2.4.2 vector capacity
[...]
5 Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is guaranteed
that no reallocation takes place during insertions that happen after a
call to reserve() until the time when an insertion would make the size
of the vector greater than the size specified in the most recent call
to reserve().


Si je comprend bien ce passage, il garantit que la capacité ne
baisse jamais (sauf éventuellement par un appel explicite à resize) ?

--drkm

Avatar
Loïc Joly
drkm wrote:
Loïc Joly writes:


23.2.4.2 vector capacity
[...]
5 Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is guaranteed
that no reallocation takes place during insertions that happen after a
call to reserve() until the time when an insertion would make the size
of the vector greater than the size specified in the most recent call
to reserve().



Si je comprend bien ce passage, il garantit que la capacité ne
baisse jamais (sauf éventuellement par un appel explicite à resize) ?


C'est aussi ce que j'y comprend, ce qui est étrange, puisque c'est
incompatible avec swap, par exemple, qui peut faire baisser la taille
d'un vector.

--
Loïc


Avatar
kanze
drkm wrote in message
news:...
Loïc Joly writes:
23.2.4.2 vector capacity
[...]
5 Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is
guaranteed that no reallocation takes place during insertions that
happen after a call to reserve() until the time when an insertion
would make the size of the vector greater than the size specified in
the most recent call to reserve().


Si je comprend bien ce passage, il garantit que la capacité ne
baisse jamais (sauf éventuellement par un appel explicite à resize) ?


En effet. Même un appel explicite à resize n'a pas le droit de la
baisser. Ni swap, ni quoique ce soit d'autre.

Dans la pratique, ce n'est pas possible à implémenter et aussi respecter
les contraints de complexité donnée (par exemple, pour swap), voir les
DR 101 et 341.

Avant les DR, ce n'était pas clair ce que voulait la norme réelement, et
différentes implémentations avaient choisies différentes solutions.

--
James Kanze GABI Software http://www.gabi-soft.fr
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


Avatar
drkm
Loïc Joly writes:

drkm wrote:

Loïc Joly writes:

23.2.4.2 vector capacity


Si je comprend bien ce passage, il garantit que la capacité ne
baisse jamais (sauf éventuellement par un appel explicite à resize) ?


C'est aussi ce que j'y comprend, ce qui est étrange, puisque c'est
incompatible avec swap, par exemple, qui peut faire baisser la taille
d'un vector.


En effet. Je vois mal comment swapper deux vecteurs en temps
constant sans swapper également les capacités. Je ne sais vraiment
pas où chercher une explication dans la norme.

--drkm



Avatar
Aurélien REGAT-BARREL
La fonction clear() d'un std::vector "vide" le conteneur (mise a 0 de la
taille, et destruction des elements contenus).
Mais sur PC (VS 2003), clear() désalloue egalement toute la place réservé
par le vector (si j'avais fais un reserve(100) avant, alors apres le clear
c'est retombé a 0).
Si je remplace clear() par resize(0), alors la mémoire reservée n'est pas
perdue.


Hello, voici la copie d'une réponse à ce sujet sur microsoft.public.vc.stl :

Carl Daniel [VC++ MVP] :
"The one that came up recently is that std::vector::clear()
forces the vector to reallocate on the next insert rather than setting the
size to 0 and keeping the existing allocation. That can be of significance
in some use cases. The workaround is to use vector.erase(begin(),end())
instead of clear(), or to modify <vector> to do that. In the forthcoming
VC8 vector::clear() is precicely erase(begin(),end())."

--
Aurélien REGAT-BARREL

Avatar
darkman_spam
wrote in message :

Dans la pratique, ce n'est pas possible à implémenter et aussi respecter
les contraints de complexité donnée (par exemple, pour swap), voir les
DR 101 et 341.


Merci pour ces références. Intéressant, le DR 101 ; je ne
connaissais pas le coup du

std::vector< T >( v ).swap( v ) ;

Mais si je comprend bien, cela n'est valable que pour les
implémentations respectant le DR 341 ?

--drkm

1 2