CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++] std::vector et "écrasement"

Caudheur
Caudheur
Niveau 8
20 août 2012 à 03:59:07

Salut à tous !

Désolé pour le titre peu explicite. Ma question concerne l'assignation d'une valeur à une case d'un std::vector qui est déjà remplie.

Par exemple :

vector.push_back(Objet());
vector[0] = Objet();

Que se passe t-il en coulisse ? Est ce que le vector appelle tout seul le destructeur de l'objet qui est écrasé ?
Et dernière question, est-ce une façon "propre" de faire ?

Merci d'avance !

godrik
godrik
Niveau 30
20 août 2012 à 04:24:24

yep

godrik
godrik
Niveau 30
20 août 2012 à 04:25:14

heu... nop,

Quand tu fais ca, ca appelle l'operateur d'affectation (operator=). Sauf si la case n'est pas encore utilise et alors ca appelle le constructeur par recopie.

Caudheur
Caudheur
Niveau 8
20 août 2012 à 05:44:22

D'accord, merci Godrik ! Et donc pour être le plus propre possible, je ferais mieux d'écrire :

delete vector[0];
vector[0] = Objet();

?

godrik
godrik
Niveau 30
20 août 2012 à 05:56:13

Caudheur, tout depend de ce que tu stocke dans ton vector. Si tu as un std::vector<T> foo; alors foo[0] = someobjectt(); appelle l'operateur d'affectation sur T.

Si T est "Object *" qui est alloue dynamiquement et qu'il faut desallouer manuellement, alors oui, il faut que tu appelle delete sur le pointeur parceque l'operateur d'affectation defini pour les pointeurs ne desalloue pas la memoire. Mais ca ne devrait JAMAIS arriver une situation comme ca en C++, tu devrais utiliser un conteneur de pointeur alloue dynamiquement comme un std::smart_ptr (ou je-ne-sais-plus-quoi que ca s'appelle maintenant).

Si T est un vrai Object, alors l'operateur d'affectation devrait etre ecrit proprement et l'operation est safe.

Caudheur
Caudheur
Niveau 8
20 août 2012 à 07:10:30

Ok, super ! Depuis notre discussions sur les vector et les pointeurs (cf https://www.jeuxvideo.com/forums/1-47-67496-1-0-1-0-c-std-vector-et-pointeurs.htm ), j'ai arrêté d'utiliser des pointeurs à tout va !

chris_27
chris_27
Niveau 10
20 août 2012 à 10:22:27

Caudheur: tu as tout faux là, non ?
Il n'y a pas de new à l'origine, donc si tu appelles delete, ton code va planter. :(

De fait, il n'y a (si ta classe Objet implante décemment ses constructeurs, son destructeur et sa surcharge de l'opérateur =) aucune question à se poser sur la gestion même de la mémoire. Pour le constater, il suffit de se souvenir que Objet ça peut très bien être int... et là tu vois tout de suite qu'on appelle jamais delete sur un int. :-)))

Caudheur
Caudheur
Niveau 8
20 août 2012 à 10:35:46

Au temps pour moi, en effet j'ai oublié de préciser pour le new dans mon post précédent.

J'essaie de me concentrer sur la gestion de la mémoire et de comprendre un peu plus en détails les mécanismes (Je navigue à contre courant de l’abstraction généralisée du C++ ? :-) )

Merci pour votre aide, et bonne journée !

chris_27
chris_27
Niveau 10
20 août 2012 à 11:08:44

« j'ai arrêté d'utiliser des pointeurs à tout va » :d) c'est pas vrai si tu fais des new/delete. :-)

C'est quoi le type de ton vecteur ? std::vector<Object*> ?

Caudheur
Caudheur
Niveau 8
20 août 2012 à 11:19:35

Non non, depuis le topic j'ai complètement arrêter de faire ce genre d'opération :-)
Le new delete dans mon post étaient plus pour l'exemple, pour comprendre le fonctionnement des vectors.

Je profite du topic pour glisser une question : le mot-clef "extern" est il propre à utiliser ? Il a l'air assez puissant, par exemple pour partager entre tous les objets graphiques l'objet qui les dessine.

Caudheur
Caudheur
Niveau 8
20 août 2012 à 11:20:27

J'ai complètement arrêté*

chris_27
chris_27
Niveau 10
20 août 2012 à 13:49:46

« le mot-clef "extern" est il propre à utiliser ? » :d) non, non et NON.

Et ce n'est pas puissant, c'est surtout signe d'un mauvais découpage du code et sources de problèmes au linkage (et Dieu sait que c'est imbuvable les erreurs de linkage).

« Il a l'air assez puissant, par exemple pour partager entre tous les objets graphiques l'objet qui les dessine. » :d) Non. Tu fais un global.hpp que tu inclus partout pour ça.

hyrulink2
hyrulink2
Niveau 7
21 août 2012 à 17:35:02

L'operator[] du vector retourne une référence sur l'objet donc en admettant que la taille de vector est >= 1,
vector[0] = Objet();
appellera toujours l’opérateur d'affectation. Sinon c'est un comportement indéterminé.

godrik
godrik
Niveau 30
21 août 2012 à 17:36:33

hyrulink2, tu peux aussi utiliser [] pour inserer un nouvel element il me semble. Dans ce cas, j'imagine que le constructeur par copie est appelle.

Note: j'ai pas verifie.

chris_27
chris_27
Niveau 10
21 août 2012 à 18:39:12

Ça plante sur un mapping où ceci ferait nettement plus sens. Alors sur un vector, ça m'étonnerait que ça marche... :peur:

http://www.cplusplus.com/reference/stl/vector/at/ est flou sur le sujet... mais si at() renvoie une exception et que [] à la même sémantique que at() hormis l'envoi d'une exception... on peut raisonnable penser que ça va "segfaulter" de faire tab[i] = x; si la case i n'est pas déjà allouée/occupée.

De toute façon, comme dit hyrulink2, le résultat est une référence. Et vu que tu peux stocker des objets sans constructeur par défaut dans ton vector, je vois mal comment l'affectation dans une case vierge pourrait marcher. :(

godrik
godrik
Niveau 30
21 août 2012 à 18:50:36

Tu n'es pas assez un gourou des templates. En renvoyant une reference sur un objet bizarres quand l'operateurbracket est utilise comme l value pourrait faire l'affaire.

Et l'insertion est supporte par map I'll me semble.

hyrulink2
hyrulink2
Niveau 7
21 août 2012 à 19:29:48

Si on est out of bound, [] peut faire n'importe quoi vu que c'est undefined behavior. Typiquement il va faire un truc genre *(vector.data() + n) donc ça va rien faire de grave si la place a déja été reservée mais l'objet ne sera pas inséré. Si la place n'a pas été reservée un segfault ou pire. En aucun cas le [] du vector ne va insérer d'éléments.
Pour une map la sémantique est complètement différente, le [] renvoie une référence sur la valeur(qui est créée à la volée si la clée n'était pas présente).

godrik
godrik
Niveau 30
21 août 2012 à 19:56:12

Mea Culpa:

erik@powell:/tmp$ cat foo.cpp

  1. include <iostream>
  2. include <vector>

int main()
{
std::vector<int> v;
std::cout<<v.size()<<std::endl;
v.push_back(2);
std::cout<<v.size()<<std::endl;
v[1] = 3;
std::cout<<v.size()<<std::endl;

return 0;
}
erik@powell:/tmp$ make foo
g++ foo.cpp -o foo
erik@powell:/tmp$ ./foo
0
1
1
erik@powell:/tmp$

Caudheur
Caudheur
Niveau 8
22 août 2012 à 01:28:11

D'accord, vraiment intéressant, j'ai appris pas mal de choses grâce à vous !

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment