Pourquoi ce code écrit-il un nombre indéfini d'entiers apparemment non initialisés?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
for (int i : vector<vector<int>>{{77, 777, 7777}}[0])
cout << i << ' ';
}
Je m'attendais à ce que la sortie soit 77 777 7777
.
Ce code est-il censé être indéfini?
using std::vector
place deusing namespace std;
afin d'éviter que cette mauvaise pratique ne se propage.En effet, le vecteur que vous parcourez sera détruit avant d'entrer dans la boucle.
C'est ce qui se produit généralement:
Les problèmes commencent à la première ligne car ils sont évalués comme suit:
Construisez d'abord le vecteur de vecteurs avec les arguments donnés et ce vecteur devient temporaire car il n'a pas de nom.
Ensuite, la référence de plage est liée au vecteur en indice qui ne sera valide que tant que le vecteur qui la contient est valide.
Une fois le point-virgule atteint, le vecteur temporaire est détruit et dans son destructeur, il détruira et désallouera tous les vecteurs stockés, y compris le vecteur en indice.
Vous vous retrouvez avec une référence à un vecteur détruit qui sera itéré.
Pour éviter ce problème, il existe deux solutions:
Déclarez le vecteur avant la boucle pour qu'il dure jusqu'à la fin de sa portée, ce qui inclut la boucle.
C ++ 20 est livré avec une instruction init qui est fournie pour résoudre ces problèmes et est meilleure que la première approche si vous voulez que le vecteur soit immédiatement détruit après la boucle:
la source
Je m'attends à ce que cela pende.
Bien que la définition d'un à distance assure que la RHS du côlon reste "vivante" pendant toute la durée, vous êtes toujours en train de souscrire un temporaire. Seul le résultat de l'indice est conservé, mais ce résultat est une référence et le vecteur réel ne peut pas survivre au-delà de l' expression complète dans laquelle il est déclaré. Cela ne décrit pas toute la boucle.
la source