2016-05-19 11 views
1

Ich entschuldige mich, dass ich immer noch sehr neu mit C++ bin, so dass Ihre Geduld geschätzt wird.Wie C++ Array mit einem Zeiger auf das erste Element zuweisen?

Als Teil einer nicht veränderbaren Einschränkung in meinem Projekt muss ich einen Vektor in ein Array konvertieren. Auf der Suche nach einer Lösung bin ich immer wieder auf Antworten wie this one gestoßen.

Wie ich verstehe, gibt diese Lösung Ihnen einen Zeiger auf das erste Element im Vektor - und da ein Vektor garantiert im Speicher zusammenhängend ist, können Sie das Array so einstellen, dass es auf diesen Speicherort (oder etwas ähnliches) zeigt Das).

Meine Frage ist jedoch, wie genau mache ich das in C++? Die Antwort scheint darauf hinzudeuten, dass es trivial ist, aber ich kann nicht finden, wie es geht.

Ich habe Dinge dieser Art versucht, aber sie funktionieren nicht ....

std::vector<double> v; 
double* a = &v[0]; 
double myArray[100]; 
&myArray[0] = a; 

einen Zeiger auf das erste Element in einer Folge gegeben, wie ich dann diesen Zeiger verwenden, um ‚bevöl ' eine Anordnung? Muss ich mich um Größenunterschiede/Out-of-Bound-Probleme kümmern? Könnte ich das auch umgekehrt machen (einen Vektor mit einem Zeiger auf das erste Element eines Arrays auffüllen)?

+0

'double * a = &v[0];' sollte funktionieren – Rakete1111

+1

@ Rakete1111 Also kann ich dann ein Array verwenden? z.B. a [3] = 1,5; – jEsp

+1

Das ist richtig :) – Rakete1111

Antwort

1

Wenn Sie einen Vektor und ein Array wie zum Beispiel

std::vector<double> v; 
double myArray[100]; 

und möchten, dass die Array-Elemente des Vektors enthalten würden Sie Elemente des Vektors in der Anordnung wie zum Beispiel kopieren sollte

std::copy(v.begin(), 
      std::next(v.begin(), std::min<std::vector<double>::size_type>(v.size(), 100)), 
      std::begin(myArray)); 

oder

std::copy(v.begin(), 
      v.begin() + std::min<std::vector<double>::size_type>(v.size(), 100), 
      myArray); 

Wenn Sie möchten, dass die Vektorelemente th haben würde e-Array, dann können Sie

v.assign(std::begin(myArray), std::end(myArray)); 

oder

v.insert(v.end(), std::begin(myArray), std::end(myArray)); 

schreiben Oder Sie können den Vektor deklarieren und zugleich (nach der Definition und das Füllen des Array) initialisieren

std::vector<double> v(std::begin(myArray), std::end(myArray)); 

dass ist das gleiche wie

std::vector<double> v(myArray, myArray + 100); 
5

Sie können Elemente nicht mit einem Zeiger auf das erste Element des Vektors in einen Vektor einfügen. Ein Vektor besitzt seinen Inhalt eindeutig und muss daher nur über seine eigene Oberfläche seine Größe ändern können, sonst kann er nicht verfolgen, wie viele Elemente er besitzt.

Sie können dies tun:

std::vector<double> v(N); // N elements initialized to 0.0 
double* a = v.data(); 
do_something(a, N); // tell the function to write N elements 
+0

Das macht Sinn. Vielen Dank. – jEsp

0

Es hängt von der Lebensdauer des Arrays und Vektor, sowie wie Sie das Array zur Verwendung.

Wenn Sie lediglich den Vektor als ein Array zugreifen möchten, können Sie es tun, so einfach wie Sie geschrieben haben:

double* myArray = &v[0]; 

Oder mit C++ 11 oder höher:

double* myArray = v.data(); 

Dann können Sie auf den Vektor zugreifen, als wäre es ein Array mit myArray. Effektiv aliasiert nur der interne Speicher des Vektors zu einem separaten Zeiger. Der tiefgestellte Operator [] arbeitet mit Zeigern, wodurch myArray mehr oder weniger als ein Array funktionieren kann.

Allerdings gibt es zwei gotchas mit diesem:

  1. die oben Willen nur richtig funktioniert, wenn die Lebensdauer von myArray vollständig durch die von v umgeben ist. Wenn der Vektor den Gültigkeitsbereich verlässt, wird er gelöscht oder wird in der Größe geändert, myArray wird ungültig gemacht. Sie zeigen lediglich auf den internen Speicher von v, so dass alles, was diesen Speicher ändert, myArray bricht.
  2. Wie in Ihrem Beispiel geschrieben, ist diese Operation nicht gültig, da Ihr Vektor v keine Größe hat. Gib ihm eine Größe, bevor du seine Adresse nimmst.

Wenn Sie wollen den Inhalt des Vektors in ein Array kopieren, können Sie memcpy() verwenden.

double* myArray = new double[v.size()]; 
memcpy(myArray, &v[0], v.size() * sizeof(double)); 

Dies wird die Anzahl der Elemente derzeit in v in myArray und füllen, die Speicher mit den in v enthaltenen Daten zuzuteilen. Änderungen an myArray sind jedoch unabhängig von v. Sie haben lediglich den Vektor in das Array kopiert.

Es gibt mehrere andere Möglichkeiten, die zweite Option zu erreichen.

+0

'std :: fill' wäre besser als' memcpy', denn dann gibt es nicht die Möglichkeit, einen Fehler mit 'sizeof' zu machen. –

+0

Sehr informative Antwort! In meinem speziellen Fall besteht das Ziel darin, dass eine Methode einen Vektor zurückgibt, der dann in ein Array konvertiert werden müsste, um ein Objekt zu instantiieren, das dieses Array als Datenelement benötigt. Es klingt also so, als würde ich wahrscheinlich mit meinem Gotcha # 1 auf ein Problem stoßen. – jEsp

0

Es ist möglich eine Array-Referenz zu machen:

vector<double> v(100); // must size the vector first, or at least add 1 element and call reserve(100) 
double (&myArray)[100] = reinterpret_cast<double(&)[100]>(v[0]); 

Dann können Sie verwenden myArray[0], myArray[1] usw. Allerdings, wenn Sie den Vektor einfügen in dann myArray ungültig wird (und es ist nicht möglich, zu ‚bewegen‘ es).

Obwohl dies möglich ist, wäre es sehr ungewöhnlich, so dass Sie es in keinem echten Code tun sollten.

Verwandte Themen