2008-11-25 12 views
5

ich einen Vektor mit 1000 „Knoten“ habedie Reservespeicher von C++ Vektor Ändern

if(count + 1 > m_listItems.capacity()) 
    m_listItems.reserve(count + 100); 

Das Problem ist, ich es auch klar, wenn ich über sie zu füllen.

m_listItems.clear(); 

Die Kapazität ändert sich nicht. Ich habe die Größe (1) verwendet; aber das scheint die Kapazität nicht zu verändern. Also wie ändert man die Reserve?

+0

Ist Ihr System nicht genügend Speicher? Reservieren bedeutet, dass das Hinzufügen von n Objekten 0 (n^2) Zeit und höchstens n + 100 Objekte mit Leerzeichen plus Rundungsfehler verwendet. Wenn der Vektor sich selbst erweitern würde, wäre weniger Code, O (n) Zeit, und bei den meisten Implementierungen wird höchstens 2 * n Leerzeichen plus Rundung verwendet. –

+0

Mein System ist sehr kurz im Speicher. (Eingebettet) .. Der Code war wirklich nur ein Beispiel für das, was ich irgendwie implementieren möchte. Zum größten Teil bekomme ich 1000 Item Chunks von der "Tabelle", so dass es sinnvoll ist, die Größe in der gleichen Häufigkeit zu ändern. Die Reinigung war mein Hauptanliegen. – baash05

Antwort

20
vector<Item>(m_listItems).swap(m_listItems); 

schrumpfen m_listItems wieder: http://www.gotw.ca/gotw/054.htm (Herb Sutter)

Wenn Sie es trotzdem löschen möchten, tauschen mit einem leeren Vektor:

vector<Item>().swap(m_listItems); 

was natürlich Art und Weise effizienter. (Beachten Sie, dass das grundlegende Austauschen von Vektoren bedeutet, dass nur zwei Zeiger ausgetauscht werden. Nichts wirklich Zeitaufwendiges)

+2

Es lohnt sich, darauf hinzuweisen, dass swap() zwar extrem billig ist, das Erstellen der temporären Kopie von m_listItems im ersten Fall jedoch das Kopieren jedes Elements im Vektor erfordert. Also, während der Vektor vollständig gelöscht wird (Einstellen der Kapazität auf 0) ist billig. Verkleinerung ist es sonst nicht. – jalf

+1

in der Tat. aber diese Sequenz ist im Wesentlichen die gleiche, die benötigt würde, wenn der Vektor selbst eine Funktion shrink() hätte. Eine Neuzuweisung wäre sowieso nötig:/ –

+1

aber Ihr Punkt ist gut, da Vektoren in C++ 1x ihre Elemente an die neue Stelle verschieben können. mein Code sollte einfach Vektor schauen (std :: move (m_listItems)). swap (m_listItems); dann denke ich –

1

Man könnte diese Technik versuchen, von here

std::vector<int> v; 
// ... fill v with stuff... 
std::vector<int>().swap(v); 
1

Sie es mit einem neuen Vektor swap kann die Kapazität gewünscht hat.

vector<int> tmp; 
old.swap(tmp); 
1

Soweit ich das beurteilen kann, können Sie einen Vektor nicht zu einer niedrigeren Kapazität als jemals neu zuweisen; Sie können es nur größer zuweisen. Dafür gibt es gute Gründe; unter ihnen ist, dass der Umwidmungsprozess sehr rechenintensiv ist. Wenn Sie wirklich einen kleineren Vektor benötigen, befreien Sie den alten und erstellen Sie einen neuen, der kleiner ist. Das ist eigentlich sehr viel einfacher, als den Vektor tatsächlich kleiner zu machen.

+0

wie schaffst du das? – baash05

+0

Hängt davon ab, wie es zugewiesen wurde - Sie lassen es entweder außerhalb des Gültigkeitsbereichs oder Sie rufen delete auf. Ich denke nicht, dass dies ein guter Ratschlag im Vergleich zum Tausch ist. –

2

Sie können den Vektor tauschen wie andere vorgeschlagen haben, und wie in http://www.gotw.ca/gotw/054.htm aber bewusst sein, beschrieben, dass es nicht frei, du bist eine Kopie jedes Elements durchführen, weil der Vektor einen neuen zuzuweisen hat, kleiner , Stück Speicher, und kopieren Sie alle alten Inhalte über. (Die Swap-Operation ist im Wesentlichen frei, aber Sie tauschen mit einem temporären mit einer Kopie der ursprünglichen Vektors Daten initialisiert, die nicht frei ist)

Wenn Sie im Voraus wissen, wie groß der Vektor ist, sollten Sie zuteilen, die richtige Größe zu beginnen, so dass keine Größenänderung ist notwendig:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements 

Und wenn Sie nicht die Kapazität im Voraus wissen, warum es keine Rolle, ob es ein wenig Platz verschwendet? Lohnt es sich, jedes Element in einen neuen und kleineren Vektor zu kopieren (was std :: vector (v) .swap (v) tun wird), nur um ein paar Kilobyte Speicher zu sparen?

In ähnlicher Weise, wenn Sie den Vektor löschen, wenn Sie beabsichtigen, es auf jeden Fall zu füllen, scheint es eine beeindruckende Verschwendung von Zeit, seine Kapazität auf Null einzustellen.

bearbeiten:

baash05: Was ist, wenn Sie ein 10 MB RAM 1000000 Artikel hatte.würden Sie sagen Reduzierung der Overhead ist wichtig?

Nr den Vektor Ändern der Größe erfordert mehr Speicher, vorübergehend, wenn Sie also speicher begrenzt sind, das könnte Ihre Anwendung brechen. (Sie müssen den Originalvektor im Speicher haben, und das temporäre, bevor Sie sie austauschen können, so dass Sie bis zu doppelt so viel RAM an diesem Punkt verwenden). Danach können Sie eine kleine Menge an Speicher speichern (bis zu ein paar MB), aber das ist egal, weil die überschüssige Kapazität im Vektor niemals aufgerufen würde, also würde es in die Auslagerungsdatei geschoben werden, und so nicht zählen Sie in erster Linie auf Ihr RAM-Limit.

Wenn Sie 1000000 Elemente haben, dann sollten Sie den Vektor auf die richtige Größe an erster Stelle initialisieren.

Und wenn Sie das nicht können, dann ist es normalerweise besser, die Kapazität allein zu lassen. Vor allem, da Sie angegeben haben, dass Sie den Vektor nachfüllen werden, sollten Sie die Kapazität, die bereits zugewiesen wurde, definitiv wiederverwenden, anstatt alles ständig zuzuordnen, neu zuzuordnen, zu kopieren und freizugeben.

Sie haben zwei mögliche Fälle. Entweder Sie wissen, wie viele Elemente Sie speichern müssen oder nicht. Wenn Sie wissen, dann können Sie den Vektor mit der richtigen Größe an erster Stelle erstellen, und so müssen Sie nie die Größe ändern, oder Sie wissen nicht, und dann können Sie genauso gut die überschüssige Kapazität behalten, so zumindest muss nicht nach oben angepasst werden, wenn Sie Ihren Vektor nachfüllen.

+0

Was wäre, wenn Sie 1000000 Elemente und 10 MB RAM hätten. Würden Sie sagen, dass die Reduzierung des Overheads wichtig ist? – baash05

+0

Nein, normalerweise nicht. Siehe meine Bearbeitung. – jalf