Un peu la question de savoir pourquoi? Vous pouvez accéder à un vecteur sous forme de tableau. Que fait un tableau qu'un vecteur ne fait pas?
Michael Dorgan
96
@Michael Le cas d'utilisation typique que j'ai utilise un vecteur dans mon propre code et a besoin d'appeler une fonction tierce qui prend un tableau
Michael Mrozek
7
La terminologie utilisée est source de confusion. Un pointeur n'est pas un tableau. Voulons-nous un pointeur vers le premier élément d'un tableau ou un tableau?
GManNickG
7
absolument une vraie question - assez simple et facile à interpréter aussi. veuillez rouvrir.
dbliss
10
"Je me demande un peu pourquoi?" - Tout d'abord, l'abus de cette phrase. Deuxièmement, il saigne clairement pourquoi.
Jim Balter
Réponses:
533
Il y a une astuce assez simple à faire, car la spécification garantit maintenant que les vecteurs stockent leurs éléments de manière contiguë:
@ganuke Vous ne copiez pas, vous créez un pointeur qui pointe vers le tableau réel que le vecteur utilise en interne. Si vous voulez copier la réponse de GMan explique comment
Michael Mrozek
4
@ganuke: Qu'est-ce que "le tableau"? Vous devez fournir plus d'informations. Quelle est la grande image?
GManNickG
6
@ganuke Non, vous avez juste besoin d'un double*qui pointe vers les mêmes données. Cette réponse fonctionne exactement pour ce cas
Michael Mrozek
6
@guneykayim Le vecteur possède cette mémoire, vous ne devriez pas la libérer
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
sinoTrinity
148
Pourquoi? Vous devez clarifier: avez-vous besoin d'un pointeur sur le premier élément d'un tableau ou d'un tableau?
Si vous appelez une fonction API qui attend la première, vous pouvez le faire do_something(&v[0], v.size()), où vest un vecteur de doubles. Les éléments d'un vecteur sont contigus.
Remarque: utilisez v.size () pour obtenir le nombre d'éléments pour le nouveau tableau: double arr [v.size ()];
rbaleksandar
7
@rbaleksandar: Les tableaux ne peuvent pas avoir une taille d'expression non constante.
GManNickG
@GManNickG: Cela fonctionne, mais je pense qu'il y a un malentendu ici. Imaginez ce qui suit: vous avez une classe avec un tas de pointeurs de différents types qui doivent pointer vers des tableaux, qui ne sont pas connus au moment où vous définissez votre classe et qui sont ensuite créés en vidant divers vecteurs et en utilisant leur paramètre de taille pour déterminer la quantité d'espace à utiliser. Un autre exemple: une fonction simple void arrayTest (unsigned int arrSize), qui crée un tableau (short arr [arrSize];) en utilisant son paramètre de fonction pour la taille.
rbaleksandar
1
@rbaleksandar Pas de malentendu; en C ++ 11 et versions antérieures, les tailles de tableau doivent être des expressions constantes intégrales. Votre exemple de fonction est une utilisation courante des VLA en C, mais uniquement pris en charge par l'extension (non standard) en C ++. Cependant, il peut arriver en C ++ 14: stackoverflow.com/a/17318040/87234 . Mais pour l'instant, ce n'est tout simplement pas une option standard.
GManNickG
1
@GManNickG Je pense que @Jet dit que si vous voulez convertir un vecteur en tableau, et que vous avez l'intention de dimensionner le tableau en utilisant la size()fonction du, std:vectorvous devrez utiliser newou mallocfaire cela. Comme cela a déjà été souligné (par vous), ce double arr[v.size()]n'est pas valable. Utiliser un vecteur à la place de nouveau est une bonne idée, mais le point essentiel de la question est de savoir comment convertir un vecteur en tableau.
Il est garanti que cela fonctionne selon la norme, mais il y a quelques mises en garde: en particulier, veillez à n'utiliser thearrayque pendant qu'il thevectorest dans le champ d'application.
Si vous avez une fonction, alors vous avez probablement ceci: foo(&array[0], array.size());. Si vous avez réussi à vous retrouver dans une situation où vous avez besoin d'un tableau, vous devez refactoriser, les vecteurs sont essentiellement des tableaux étendus, vous devez toujours les utiliser.
Réponses:
Il y a une astuce assez simple à faire, car la spécification garantit maintenant que les vecteurs stockent leurs éléments de manière contiguë:
la source
double*
qui pointe vers les mêmes données. Cette réponse fonctionne exactement pour ce casstd::vector<double> v; double* a = v.data();
Pourquoi? Vous devez clarifier: avez-vous besoin d'un pointeur sur le premier élément d'un tableau ou d'un tableau?
Si vous appelez une fonction API qui attend la première, vous pouvez le faire
do_something(&v[0], v.size())
, oùv
est un vecteur dedouble
s. Les éléments d'un vecteur sont contigus.Sinon, il vous suffit de copier chaque élément:
Assurez-vous non seulement qu'il
arr
est assez grand, mais qu'ilarr
est rempli, ou que vous avez des valeurs non initialisées.la source
size()
fonction du,std:vector
vous devrez utilisernew
oumalloc
faire cela. Comme cela a déjà été souligné (par vous), cedouble arr[v.size()]
n'est pas valable. Utiliser un vecteur à la place de nouveau est une bonne idée, mais le point essentiel de la question est de savoir comment convertir un vecteur en tableau.Pour C ++ 11 ,
vector.data()
fera l'affaire.la source
Il est garanti que cela fonctionne selon la norme, mais il y a quelques mises en garde: en particulier, veillez à n'utiliser
thearray
que pendant qu'ilthevector
est dans le champ d'application.la source
empty()
, sinon cela invoquerait l'UB redouté.Les vecteurs sont efficacement des réseaux sous la peau. Si vous avez une fonction:
vous pouvez l'appeler comme ceci:
Vous ne devriez jamais avoir besoin de convertir un vecteur en une véritable instance de tableau.
la source
f( &v[0] );
pour votre dernière ligneQuant à
std::vector<int> vec
vec pour obtenirint*
, vous pouvez utiliser deux méthodes:int * arr = & vec [0];
int * arr = vec.data ();
Si vous souhaitez convertir n'importe quel type de
T
vecteur enT* array
, remplacez simplement ce qui précèdeint
parT
.Je vais vous montrer pourquoi les deux ci-dessus fonctionnent, pour une bonne compréhension?
std::vector
est un tableau dynamique essentiellement.Membre des données principales comme ci-dessous:
le
range (start_, end_of_storage_)
est toute la mémoire du tableau allouée par le vecteur;le
range(start_, finish_)
est toute la mémoire matricielle du vecteur utilisé;le
range(finish_, end_of_storage_)
est la mémoire de tableau de sauvegarde.Par exemple, comme pour un vecteur vec. qui a {9, 9, 1, 2, 3, 4} est le pointeur peut aimer le ci-dessous.
So
&vec[0]
= start_ (address.) (Start_ est équivalent à int * array head)Dans
c++11
ladata()
fonction membre, renvoyez simplement start_la source
Nous pouvons le faire en utilisant la méthode data (). C ++ 11 fournit cette méthode.
Extrait de code
la source
la source
Si vous avez une fonction, alors vous avez probablement ceci:
foo(&array[0], array.size());
. Si vous avez réussi à vous retrouver dans une situation où vous avez besoin d'un tableau, vous devez refactoriser, les vecteurs sont essentiellement des tableaux étendus, vous devez toujours les utiliser.la source
Vous pouvez faire quelque chose comme ça
la source