web-dev-qa-db-fra.com

Pointeur vectoriel de déréférence pour accéder à l'élément

Si j'ai en C++ un pointeur vers un vecteur:

vector<int>* vecPtr;

Et je voudrais accéder à un élément du vecteur, alors je peux le faire en déréfernançant le vecteur:

int a = (*vecPtr)[i];

mais ce déréférencement créera-t-il réellement une copie de mon vecteur sur la pile? disons que le vecteur stocke 10000 ints, en déréférençant les vecPtr 10000 ints seront copiés?

Merci!

49
Mat

10000 ints ne seront pas copiés. Le déréférencement est très bon marché.

Pour être clair, vous pouvez réécrire

int a = (*vecPtr)[i];

comme

vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];

De plus, si vous avez peur que toutes les données stockées dans vector se trouvent sur la pile et que vous utilisez vector<int>* au lieu de vector<int> pour éviter cela: ce n'est pas le cas. En fait, seule une quantité fixe de mémoire est utilisée sur la pile (environ 16-20 octets selon l'implémentation), indépendamment du nombre d'éléments stockés dans le vector. Le vector lui-même alloue de la mémoire et stocke des éléments sur le tas.

59
sergtk

Non, rien ne sera copié; le déréférencement indique simplement à C++ que vous voulez appeler l'opérateur [] sur le vecteur, pas sur votre pointeur, vecPtr. Si vous ne déréférencez pas, C++ essaiera de rechercher un opérateur [] défini sur le type std::vector<int>*.

Cela peut devenir très déroutant, car operator[] Est défini pour tous les types de pointeurs, mais cela revient à décaler le pointeur comme s'il pointait vers un tableau de vector<int>. Si vous n'y aviez vraiment alloué qu'un seul vecteur, alors pour tout index autre que 0, L'expression est évaluée en référence aux ordures, vous obtiendrez donc soit un défaut de segmentation ou quelque chose que vous ne vous attendiez pas.

En général, l'accès aux vecteurs via un pointeur est pénible et la syntaxe (*vecPtr)[index] Est maladroite (mais meilleure que vecPtr->operator[](index)). Au lieu de cela, vous pouvez utiliser:

vecPtr->at(index)

Cela vérifie en fait les plages, contrairement à operator[], Donc si vous ne voulez pas payer le prix pour vérifier si l'index est dans les limites, vous êtes coincé avec (*vecPtr)[].

46
Todd Gamblin