3 votes

Est-il dangereux d'utiliser un pointeur vers un élément dans un vecteur?

J'ai un vecteur, rempli d'objets :

std::vector vec;
vec.push_back(MyClass("Salut", 10)); //exemple, pourrait être n'importe quelle classe

Plus tard, lorsqu'il est rempli, je veux y accéder :

for(unsigned int i = 0; i < vec.size(); i++)
{
  MyClass *c = & vec.at(i); // <--- ICI
  if(c)                     // <--- ET ICI
  {
    c->membreDeMaClasse = x;
  }
}

Est-ce plus dangereux d'utiliser c que d'utiliser vec.at(i) directement ? Ai-je besoin de la protection avec if(c) ? c peut-il être nullptr ? Je suppose que non, car le vecteur prend des objets, pas des pointeurs vers des objets.

2voto

molbdnilo Points 9289

Un pointeur que vous acquérez avec & ne peut pas être nul, donc il n'y a aucun danger et aucun intérêt à vérifier.

(Vous pourriez penser à la manière dont un pointeur vers un élément peut devenir invalide si vous ajoutez ou supprimez des éléments du vecteur, mais il ne deviendra jamais nul et vous ne pourrez pas le détecter.)

Il est courant d'utiliser une référence dans cette situation :

MyClass& c = vec.at(i);
c.member = x;

mais avec votre boucle spécifique, envisagez d'utiliser une boucle de plage à la place :

for (auto& c : vec)
{
    c.member = x;
}

2voto

user2079303 Points 4916

Est-ce que l'utilisation de c est plus dangereuse que d'utiliser vec.at(i) directement?

Non, dans l'exemple. Cependant, c'est inutilement complexe.

Est-ce que c peut être nullptr?

Non, dans l'exemple.

Est-ce que j'ai besoin de la protection avec if(c)?

Non; voir ci-dessus.

Est-ce que l'utilisation d'un pointeur vers un élément dans un vector est dangereuse?

L'utilisation d'un pointeur - ou de toute autre forme d'indirection - en général peut être "dangereuse" dans le sens où les durées de vie du pointeur et de l'objet pointé sont séparées. Vous devez donc être conscient de la durée de vie de l'objet pointé car si elle est plus courte que le pointeur, alors le pointeur sera laissé "suspendu". Supposer incorrectement la durée de vie peut entraîner un comportement non défini.

Un exemple de programme défectueux:

std::vector vec{
    {"Salut", 10},
};
MyClass *c = &vec.at(0);          // OK
vec.emplace_back("Salut à nouveau", 42); // c peut être invalide maintenant
c->memberOfMyClass = x;           // comportement potentiellement non défini

0voto

sklott Points 1308

Tout d'abord, il est préférable d'utiliser une référence plutôt qu'un pointeur.

Vous n'avez pas besoin de vérifier le pointeur si vous êtes sûr d'avoir au moins i éléments dans le vecteur.

Vous pouvez utiliser une référence/un pointeur tant que les itérateurs ne sont pas invalidés. Lisez la section "Invalidation de l'itérateur" ici : https://en.cppreference.com/w/cpp/container/vector

0voto

C'est une meilleure façon d'accéder, si vous devez effectuer plusieurs accès au même élément du vecteur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X