Wie bekomme ich einen std :: vector Zeiger auf die Rohdaten?

160

Ich versuche, std::vectorals charArray zu verwenden.

Meine Funktion nimmt einen leeren Zeiger auf:

void process_data(const void *data);

Bevor ich einfach diesen Code verwendet habe:

char something[] = "my data here";
process_data(something);

Welches hat wie erwartet funktioniert.

Aber jetzt brauche ich die Dynamik von std::vector, also habe ich stattdessen diesen Code ausprobiert:

vector<char> something;
*cut*
process_data(something);

Die Frage ist, wie ich den Zeichenvektor an meine Funktion übergebe, damit ich auf die Vektorrohdaten zugreifen kann (egal welches Format es ist - Floats usw.).

Ich habe es versucht:

process_data(&something);

Und das:

process_data(&something.begin());

Aber es gab einen Zeiger auf Kauderwelschdaten zurück, und dieser warnte : warning C4238: nonstandard extension used : class rvalue used as lvalue.

Anfänger
quelle

Antworten:

238

&somethinggibt Ihnen die Adresse des std::vectorObjekts, nicht die Adresse der darin enthaltenen Daten. &something.begin()gibt Ihnen die Adresse des von zurückgegebenen Iterators an begin()(wie der Compiler warnt, ist dies technisch nicht zulässig, da something.begin()es sich um einen rvalue-Ausdruck handelt, sodass seine Adresse nicht verwendet werden kann).

Angenommen, der Container enthält mindestens ein Element, müssen Sie die Adresse des ursprünglichen Elements des Containers abrufen, über das Sie sie erhalten können

  • &something[0]oder &something.front()(die Adresse des Elements bei Index 0) oder

  • &*something.begin()(Die Adresse des Elements, auf das der von zurückgegebene Iterator zeigt begin()).

In C ++ 11 wurde eine neue Elementfunktion hinzugefügt zu std::vector: data(). Diese Mitgliedsfunktion gibt genau wie die Adresse des ursprünglichen Elements im Container zurück &something.front(). Der Vorteil dieser Mitgliedsfunktion ist, dass es in Ordnung ist, sie aufzurufen, auch wenn der Container leer ist.

James McNellis
quelle
103
Wichtig Beachten Sie, dass vector<bool>dies die Ausnahme von dieser Antwort ist (und keinen zusammenhängenden Speicher von bools hat).
Motti
18
Auf der positiven Seite gibt es nicht viel zu beachten: Alle drei Methoden lassen sich nicht kompilieren, std::vector<bool>da std::vector<bool>ein Proxy-Objekt verwendet werden muss und dieser Proxy nicht implizit in a konvertiert werden kann bool*. Als Problemumgehung boolist es am besten , wenn Sie eine Sequenz von benötigen , einfach eine zu verwenden std::vector<char>. @ Motti
James McNellis
Es stimmt, die Vorsicht war im Allgemeinen und nicht als Ihre Antwort gerichtet, da es keinen zusammenhängenden Speicher gibt, gibt es keine Möglichkeit, darauf zuzugreifen.
Motti
7
up für eine umfassende sein , aber vor allem für .data()- I'lll ich einfach so tun , nicht sehen , dass hässlich &*iterator: P
underscore_d
2
Wie lange wird der Zeiger von data()live zurückkehren? Wenn die Größe des Vektors weder größer noch kleiner geändert wird (über push_back()oder andere Funktionen, einschließlich reserve), ist dann garantiert, dass der Zeiger so lange lebt, wie der Vektor lebt, und auf die richtige Stelle zeigt?
Johnbakers
81

something.data() gibt einen Zeiger auf den Datenraum des Vektors zurück.

Chris Dodd
quelle
error C2039: 'data' : is not a member of 'std::vector<_Ty>'
Rookie
2
@Rookie: Sieht aus, als würden Sie einen kaputten Compiler verwenden - 23.3.6.3 in der C ++ - Spezifikation definiert vector :: data. Versuchen Sie, einen Fehler bei Ihrem Anbieter einzureichen oder einen besseren Compiler zu erhalten.
Chris Dodd
1
@ Chris Dodd Ich habe den gleichen Fehler. Ich benutze Visual Studio 2008.
bodacydo
34
@ ChrisDodd: vector::data()ist neu in C ++ 11
HighCommander4
Ich benutze Visual Studio 2012 und sie müssen den vector :: data () hinzugefügt haben, weil ich ihn ein paar Mal benutze.
Robert Snyder
12

Nehmen Sie stattdessen einen Zeiger auf das erste Element:

process_data (&something [0]);
Steven Don
quelle
Ich dachte, dass es die Speicheradresse des ersten Elements auch ohne die tiefgestellten Klammern zurückgeben würde?
Tim
Das ist für Arrays, nicht für Vektoren.
Steven Don
Ja, das ist mir gerade klar geworden, sorry.
Tim