Wie kann man einen std :: Vektor auf eine speichereffiziente Art und Weise verkleinern?

8

Ich möchte ein std::vector verkleinern, um seine Kapazität auf seine exakte Größe zu reduzieren, so dass zusätzlicher Speicher freigegeben wird. Der Standardtrick scheint hier der hier zu sein:

%Vor%

Der Sinn von shrink-to-fit ist es, Speicher zu sparen, aber erstellt diese Methode nicht zuerst eine tiefe Kopie und tauscht dann die Instanzen aus? Irgendwann - wenn die Kopie erstellt wird - verdoppelt sich die Speicherbelegung?

Wenn das der Fall ist, gibt es eine speicherfreundlichere Methode der Schrumpfpassung? (In meinem Fall ist der Vektor wirklich groß und ich kann es mir nicht leisten, sowohl das Original als auch eine Kopie davon jederzeit im Speicher zu haben.)

    
Frank 23.04.2010, 01:05
quelle

2 Antworten

3

Nun, wenn Sie die Größe eines Arrays ändern wollten, was würden Sie tun? Sie müssen einen neuen erstellen und alle Werte kopieren - sei es einzeln oder mit memcpy oder was auch immer. Sie können die Größe eines Arrays in C oder C ++ nicht wirklich ändern.

std::vector ist ziemlich sicher, dass es mit einem Array für seinen Speicher implementiert wird (IIRC, der Standard garantiert nicht, dass es ein Array ist, aber ein Array ist das einzige, das die verschiedenen Anforderungen der API erfüllen kann, wie z wie effizient jede Operation sein muss, so ist es tatsächlich garantiert, selbst wenn diese Garantie nicht explizit ist. Da es mit einem Array implementiert wurde und Sie die Größe von Arrays nicht ändern können, ohne zu kopieren, können Sie die Größe von Vektoren nicht ändern, ohne sie zu kopieren.

Sie könnten theoretisch eine shrink_capacity() -Funktion haben, die die Tatsache verbarg, dass Sie ihre Größenanforderungen vorübergehend mehr oder weniger verdoppeln mussten, aber da std::vector momentan keine solche Funktion hat, müssen Sie eigentlich machen eine explizite Kopie. Der Tausch Trick ist nur eine nette Möglichkeit, das zu tun.

Wenn Sie in einem solchen Fall wirklich an Speicher interessiert sind, können Sie Zeiger (oder Smart Pointer) verwenden, anstatt dass der Vektor die Objekte direkt hält. Das mag nicht unbedingt wünschenswert sein, aber es würde Ihre Speicheranforderungen reduzieren.

    
Jonathan M Davis 23.04.2010 01:15
quelle
-1

Wenn Ihre neue Größe die Hälfte des Originals ist, können Sie mit der Platzierung Ihres neuen Vektors (oder eines geraden dynaimc Arrays, wenn Vektor dies nicht kann) in den unbenutzten Endbereich Ihres alten Vektors kommen. Nicht sicher, ob Vektor Informationen in diesem Bereich des Gedächtnisses speichert, also würde dieses sehr hacky und gruselig sein. Aber es ist eine Idee.

Nun, da ich darüber nachdenke, würde eine Operation vom Typ memMove (), bei der Sie die Information rückwärts vom letzten im Original verwendeten Index auf die Rückseite des unbenutzten Bereichs im Original kopieren, die Daten beibehalten. Wenn Sie dies zu einer Neupositionierung eines Arrays gemacht haben, könnten Sie dorthin zeigen, wo die neuen Daten in der Mitte des ursprünglichen Speicherbereichs existieren würden. Ein an Ort und Stelle Umzug per se.

    
Michael Dorgan 23.04.2010 01:21
quelle

Tags und Links