Ich habe ein Array von Werten, die von einem anderen Teil des Programms an meine Funktion übergeben werden, den ich für die spätere Verarbeitung speichern muss. Da ich nicht weiß, wie oft meine Funktion aufgerufen wird, bevor die Daten verarbeitet werden müssen, benötige ich eine dynamische Speicherstruktur. Daher habe ich eine ausgewählt std::vector
. Ich möchte nicht die Standardschleife für push_back
alle Werte einzeln ausführen müssen, es wäre schön, wenn ich alles einfach mit etwas ähnlichem kopieren könnte memcpy
.
vec.assign(a, a+n)
, was kompakter wäre als Kopieren und Ändern der Größe.Hier gab es viele Antworten, und fast alle werden die Arbeit erledigen.
Es gibt jedoch einige irreführende Ratschläge!
Hier sind die Optionen:
Um es kurz zu machen: Methode 4 mit vector :: insert ist das Beste für das Szenario von bsruth.
Hier sind einige wichtige Details:
Methode 1 ist wahrscheinlich am einfachsten zu verstehen. Kopieren Sie einfach jedes Element aus dem Array und schieben Sie es in die Rückseite des Vektors. Leider ist es langsam. Da es eine Schleife gibt (impliziert mit der Kopierfunktion), muss jedes Element einzeln behandelt werden. Aufgrund der Tatsache, dass wir wissen, dass das Array und die Vektoren zusammenhängende Blöcke sind, können keine Leistungsverbesserungen vorgenommen werden.
Methode 2 ist eine vorgeschlagene Leistungsverbesserung gegenüber Methode 1; Reservieren Sie einfach die Größe des Arrays vor dem Hinzufügen. Für großen Arrays dies könnte helfen. Der beste Rat hier ist jedoch, niemals Reserve zu verwenden, es sei denn, die Profilerstellung deutet darauf hin, dass Sie möglicherweise eine Verbesserung erzielen können (oder Sie müssen sicherstellen, dass Ihre Iteratoren nicht ungültig werden). Bjarne stimmt zu . Übrigens stellte ich fest, dass diese Methode die meiste Zeit am langsamsten lief, obwohl ich Schwierigkeiten habe, umfassend zu erklären, warum sie regelmäßig signifikant langsamer war als Methode 1 ...
Methode 3 ist die Lösung der alten Schule - werfen Sie etwas C auf das Problem! Funktioniert gut und schnell für POD-Typen. In diesem Fall muss die Größe geändert werden, da memcpy außerhalb der Grenzen des Vektors arbeitet und es keine Möglichkeit gibt, einem Vektor mitzuteilen, dass sich seine Größe geändert hat. Abgesehen davon, dass dies eine hässliche Lösung ist (Byte-Kopieren!), Denken Sie daran, dass dies nur für POD-Typen verwendet werden kann . Ich würde diese Lösung niemals verwenden.
Methode 4 ist der beste Weg. Die Bedeutung ist klar, es ist (normalerweise) die schnellste und es funktioniert für alle Objekte. Die Verwendung dieser Methode für diese Anwendung hat keinen Nachteil.
Methode 5 ist eine Optimierung von Methode 4 - kopieren Sie das Array in einen Vektor und hängen Sie es dann an. Gute Option - im Allgemeinen schnell und klar.
Schließlich wissen Sie, dass Sie Vektoren anstelle von Arrays verwenden können, oder? Selbst wenn eine Funktion Arrays im C-Stil erwartet, können Sie Vektoren verwenden:
Hoffe das hilft jemandem da draußen!
quelle
&expr
nicht ausgewertet wirdexpr
, sondern nur die Adresse davon berechnet wird. Und ein Zeiger einer nach dem letzten Element ist vollkommen gültig, auch.dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
- erscheint mir viel klarer. Kann auch mit Methode 5 nichts erreichen, sieht nur ziemlich ineffizient aus - es sei denn, der Compiler kann den Vektor wieder optimieren.Wenn Sie nur die vorhandenen Daten ersetzen, können Sie dies tun
quelle
std :: copy ist das, wonach Sie suchen.
quelle
Da ich nur meine eigene Antwort bearbeiten kann, werde ich aus den anderen Antworten auf meine Frage eine zusammengesetzte Antwort erstellen. Vielen Dank an alle, die geantwortet haben.
Mit std :: copy wird dies immer noch im Hintergrund wiederholt, aber Sie müssen den Code nicht eingeben.
Mit normalem memcpy . Dies wird wahrscheinlich am besten für grundlegende Datentypen (dh int) verwendet, jedoch nicht für komplexere Arrays von Strukturen oder Klassen.
quelle
Vermeiden Sie das Memcpy, sage ich. Kein Grund, sich mit Zeigeroperationen herumzuschlagen, es sei denn, Sie müssen es wirklich tun. Außerdem funktioniert es nur für POD-Typen (wie int), schlägt jedoch fehl, wenn Sie mit Typen arbeiten, die eine Konstruktion erfordern.
quelle
quelle
myints
?Eine weitere Antwort: Da die Person sagte "Ich weiß nicht, wie oft meine Funktion aufgerufen wird", können Sie die Methode zum Einfügen von Vektoren verwenden, um Arrays von Werten an das Ende des Vektors anzuhängen:
Ich mag diesen Weg, weil die Implementierung des Vektors in der Lage sein sollte, den besten Weg zum Einfügen der Werte basierend auf dem Iteratortyp und dem Typ selbst zu optimieren. Sie antworten etwas auf die Implementierung von stl.
Wenn Sie die schnellste Geschwindigkeit garantieren müssen und wissen, dass Ihr Typ ein POD-Typ ist, würde ich die Methode zur Größenänderung in Thomas 'Antwort empfehlen:
quelle
Zusätzlich zu den oben dargestellten Methoden müssen Sie sicherstellen, dass Sie entweder std :: Vector.reserve (), std :: Vector.resize () verwenden oder den Vektor auf Größe konstruieren, um sicherzustellen, dass Ihr Vektor genügend Elemente enthält es, um Ihre Daten zu halten. Wenn nicht, wird der Speicher beschädigt. Dies gilt entweder für std :: copy () oder memcpy ().
Dies ist der Grund für die Verwendung von vector.push_back (). Sie können nicht über das Ende des Vektors hinaus schreiben.
quelle
Angenommen, Sie wissen, wie groß das Element im Vektor ist:
http://www.cppreference.com/wiki/stl/vector/start
quelle