2011-04-12 5 views
0

Comme je comprends si je ne stocke pas de pointeurs, tout en C++ est copié, ce qui peut conduire à de mauvaises performances (ignorer la simplicité de mon exemple). Donc je pensais stocker mes objets comme des pointeurs au lieu d'un objet string à l'intérieur de mon vecteur, c'est mieux pour la performance? (Assumant j'ai de très longues ficelles et beaucoup d'entre eux).C++ vecteurs et pointeurs

Le problème lorsque je tente de itérer sur mon vecteur de pointeurs de chaîne est je ne peux pas extraire la valeur réelle de leur

string test = "my-name"; 
vector<string*> names(20); 
names.push_back(&test); 

vector<string*>::iterator iterator = names.begin(); 
while (iterator != names.end()) 
{ 
    std::cout << (*iterator) << ":" << std::endl; 
    // std::cout << *(*iterator); // fails 

    iterator++; 
} 

Voir la ligne a commenté, je n'ai aucun problème à recevoir le pointeur de la chaîne. Mais quand j'essaye d'obtenir la valeur de pointeurs de chaîne j'obtiens une erreur (je ne pourrais pas trouver ce qu'excute exactement l'erreur est mais le programme échoue juste).

J'ai également essayé de stocker (itérateur) dans une nouvelle chaîne variable et mais cela n'a pas aidé?

+0

@mads Echoue? Prend une exception? Ne compile pas? Le test est-il toujours dans la portée? – Lou

+0

null pointeurs et pointeurs vers des variables d'étendue locales? pas étonnant que vous ayez des problèmes pour obtenir les valeurs réelles qu'ils pointent à –

+0

Avez-vous profilé votre code et prouvé que c'est un problème acutal? Ou êtes-vous en micro-optimisation prematureley? –

Répondre

5

Vous avez créé le vecteur et l'avez initialisé pour qu'il contienne 20 éléments. Ces éléments sont initialisés par défaut, ce qui dans le cas d'un pointeur est un pointeur nul. Le programme rencontre des problèmes pour déréférencer ces pointeurs NULL.

Un conseil est de ne pas s'inquiéter de ce qui est le plus efficace jusqu'à ce que vous ayez un problème démontré. Ce code fonctionnerait certainement beaucoup mieux avec un vector<string> par rapport à un vector<string*>.

+0

Merci, cela a beaucoup de sens lorsque vous en enveloppez la tête :) –

0

Votre code a l'air de stocker un pointeur vers une variable basée sur une pile dans un vecteur. Dès que la fonction où votre chaîne est déclarée est renvoyée, cette chaîne devient inutilisable et le pointeur est invalide. Si vous voulez stocker des pointeurs dans un vecteur, vous devez probablement allouer vos chaînes dynamiquement (en utilisant new).

0

Jetez un oeil à votre initialisation:

string test = "my-name"; 
vector<string*> names(20); 
names.push_back(&test); 

Vous créez un std::vector avec 20 éléments.

Ensuite, vous utilisez push_back pour ajouter un 21ème élément, qui pointe vers un string valide. C'est bien, mais cet élément n'est jamais atteint dans la boucle: la première itération se bloque déjà puisque les 20 premiers pointeurs stockés dans le vecteur ne pointent pas vers string s valide. Le déréférencement d'un pointeur non valide provoque un blocage.

Si vous vous assurez que vous avez des pointeurs valides dans votre vecteur, **iterator est très bien pour accéder à un élément.

0

Essayez

if (*iterator) 
{ 
    std::cout << *(*iterator) << ":" << std::endl; 
} 

Ransom Mark explique pourquoi certains des pointeurs sont maintenant

1

Non, non, mille fois non.

Ne pas optimiser prématurément. Si le programme est rapide, il n'y a pas besoin de s'inquiéter des performances. Dans ce cas, les pointeurs réduisent nettement les performances en consommant de la mémoire et du temps, puisque chaque objet n'est que la cible d'un seul pointeur! Sans oublier que la programmation manuelle des pointeurs tend à introduire des erreurs, en particulier pour les débutants. Sacrifier l'exactitude et la stabilité pour la performance est un énorme pas en arrière.

L'avantage de C++ est qu'il simplifie le processus d'optimisation en fournissant des structures de données encapsulées et des algorithmes. Ainsi, lorsque vous décidez d'optimiser, vous pouvez généralement le faire en échangeant des pièces standard. Si vous voulez en savoir plus sur l'optimisation des structures de données, lisez smart pointers.

Ceci est probablement le programme que vous voulez:

vector<string> names(20, "my-name"); 

for (vector<string>::iterator iterator = names.begin(); 
     iterator != names.end(); 
     ++ iterator) 
{ 
    std::cout << *iterator << '\n'; 
} 
0
string test = "my-name"; 
vector<string*> names(20); 

Le size du vecteur est 20, ce qui signifie qu'il peut contenir 20 pointeurs de chaîne.

names.push_back(&test); 

Avec l'opération push_back, vous quittez les 20 premiers éléments et l'ajout d'un nouvel élément au vecteur qui contient l'adresse de test. Les 20 premiers éléments du vecteur ne sont pas initialisés et pourraient pointer vers des ordures. Et la boucle while s'exécute jusqu'à la fin du vecteur dont la taille est 21 et le déréférencement des pointeurs non initialisés est ce qui cause le problème. Depuis la taille de vector peut être dynamiquement augmentée avec une opération push_back, il n'est pas nécessaire de mentionner explicitement la taille.

vector<string*> names; // Not explicitly mentioning the size and the rest of 
         // the program should work as expected.