@ganuke Nie kopiujesz, tworzysz wskaźnik wskazujący na rzeczywistą tablicę, której wektor używa wewnętrznie. Jeśli chcesz skopiować odpowiedź GMana, wyjaśnij, jak
Michał Mrożek
4
@ganuke: Co to jest „tablica”? Musisz podać więcej informacji. Jaki jest wielki obraz?
GManNickG
6
@ganuke Nie, potrzebujesz tylko double*tego, który wskazuje na te same dane. Ta odpowiedź działa dokładnie w tej sprawie
Michael Mrozek
6
@guneykayim Wektor posiada tę pamięć, nie powinieneś jej zwalniać
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
sinoTrinity,
148
Po co? Musisz wyjaśnić: Czy potrzebujesz wskaźnika do pierwszego elementu tablicy, czy tablicy?
Jeśli wywołujesz funkcję API, która oczekuje pierwszej, możesz zrobić do_something(&v[0], v.size()), gdzie vjest wektor doubles. Elementy wektora są ciągłe.
W przeciwnym razie wystarczy skopiować każdy element:
Uwaga: użyj v.size (), aby uzyskać liczbę elementów dla nowej tablicy: double arr [v.size ()];
rbaleksandar,
7
@rbaleksandar: Tablice nie mogą mieć nie stałej wielkości wyrażenia.
GManNickG,
@GManNickG: Działa, ale myślę, że jest tu trochę nieporozumień. Wyobraź sobie, że: masz klasę z szeregiem wskaźników różnych typów, które muszą wskazywać na tablice, które nie są znane w momencie definiowania twojej klasy i które są później tworzone przez opróżnianie różnych wektorów i użycie ich parametru size aby określić, ile miejsca ma zostać wykorzystane. Kolejny przykład: prosta funkcja void arrayTest (unsigned int arrSize), która tworzy w niej tablicę (short arr [arrSize];) za pomocą parametru funkcji dla wielkości.
rbaleksandar
1
@rbaleksandar Bez nieporozumień; w C ++ 11 i wcześniejszych rozmiarach tablic muszą być integralnymi stałymi wyrażeniami. Twój przykład funkcji jest powszechnym zastosowaniem dla VLA w C, ale obsługiwany tylko przez (niestandardowe) rozszerzenie w C ++. Może jednak pochodzić z C ++ 14: stackoverflow.com/a/17318040/87234 . Ale na razie nie jest to po prostu standardowa opcja.
GManNickG,
1
@GManNickG Myślę, że @Jet mówi, że jeśli chcesz przekonwertować wektor na tablicę i zamierzasz zmienić tablicę za pomocą size()funkcji std:vector, musisz użyć newlub malloczrobić to. Jak już zostało wskazane (przez ciebie), double arr[v.size()]to nie jest poprawne. Używanie wektora zamiast nowego jest dobrym pomysłem, ale cała kwestia dotyczy tego, jak przekonwertować wektor na tablicę.
Jest to gwarantowane, że działa zgodnie ze standardem, jednak istnieją pewne zastrzeżenia: w szczególności uważaj, aby używać tylko, thearraygdy thevectorjest objęty zakresem.
Jeśli masz funkcję, to prawdopodobnie potrzebujesz to: foo(&array[0], array.size());. Jeśli udało ci się dostać do sytuacji, w której potrzebujesz tablicy, musisz refaktoryzować, wektory są w zasadzie rozszerzonymi tablicami, zawsze powinieneś ich używać.
Odpowiedzi:
Jest to dość prosta sztuczka, ponieważ specyfikacja gwarantuje teraz, że wektory przechowują swoje elementy w sposób ciągły:
źródło
double*
tego, który wskazuje na te same dane. Ta odpowiedź działa dokładnie w tej sprawiestd::vector<double> v; double* a = v.data();
Po co? Musisz wyjaśnić: Czy potrzebujesz wskaźnika do pierwszego elementu tablicy, czy tablicy?
Jeśli wywołujesz funkcję API, która oczekuje pierwszej, możesz zrobić
do_something(&v[0], v.size())
, gdziev
jest wektordouble
s. Elementy wektora są ciągłe.W przeciwnym razie wystarczy skopiować każdy element:
Upewnij się, że nie tylko thar
arr
jest wystarczająco duży, ale żearr
się zapełni lub masz niezainicjowane wartości.źródło
size()
funkcjistd:vector
, musisz użyćnew
lubmalloc
zrobić to. Jak już zostało wskazane (przez ciebie),double arr[v.size()]
to nie jest poprawne. Używanie wektora zamiast nowego jest dobrym pomysłem, ale cała kwestia dotyczy tego, jak przekonwertować wektor na tablicę.Dla c ++ 11 ,
vector.data()
rade.źródło
Jest to gwarantowane, że działa zgodnie ze standardem, jednak istnieją pewne zastrzeżenia: w szczególności uważaj, aby używać tylko,
thearray
gdythevector
jest objęty zakresem.źródło
empty()
, w przeciwnym razie wywołałoby to przerażającego UB.Wektory skutecznie to tablice pod skórą. Jeśli masz funkcję:
możesz to tak nazwać:
Nie trzeba nigdy przekształcać wektora w rzeczywistą instancję tablicy.
źródło
f( &v[0] );
ostatnią linięCo do
std::vector<int> vec
vec, aby uzyskaćint*
, możesz użyć dwóch metod:int * arr = & vec [0];
int * arr = vec.data ();
Jeśli chcesz przekonwertować dowolny
T
wektor typuT* array
, po prostu zamień powyższyint
naT
.Pokażę ci, dlaczego powyższe dwa działa, dla dobrego zrozumienia?
std::vector
jest zasadniczo tablicą dynamiczną.Główny członek danych, jak poniżej:
Jest
range (start_, end_of_storage_)
to cała pamięć macierzy, którą przydziela wektor;Jest
range(start_, finish_)
to cała pamięć tablicowa, której użył wektor;Jest
range(finish_, end_of_storage_)
to pamięć macierzy kopii zapasowych.Na przykład co do wektora vec. który ma {9, 9, 1, 2, 3, 4} to wskaźnik może polubić poniżej.
So
&vec[0]
= start_ (adres.) (Start_ jest równoważne int * head tablicy)W
c++11
tejdata()
funkcji użytkownik po prostu wrócić start_źródło
Możemy to zrobić za pomocą metody data (). C ++ 11 zapewnia tę metodę.
Fragment kodu
źródło
źródło
Jeśli masz funkcję, to prawdopodobnie potrzebujesz to:
foo(&array[0], array.size());
. Jeśli udało ci się dostać do sytuacji, w której potrzebujesz tablicy, musisz refaktoryzować, wektory są w zasadzie rozszerzonymi tablicami, zawsze powinieneś ich używać.źródło
Możesz zrobić coś takiego
źródło