Ich muss ein dynamisch zugewiesenes Array (von a = new double [100] zum Beispiel) in std :: vector (vorzugsweise) verpacken, ohne das Array zu kopieren. Diese Einschränkung wird dadurch verursacht, dass das Array, das ich umhüllen möchte, aus einer Datei mmaped ist, so dass die Vektorspeicherung (a, a + size) die Speicherbelegung verdoppelt.
Gibt es irgendwelche Tricks, um das zu tun?
Eine der besten Lösungen dafür ist so etwas wie STLSoft array_proxy & lt; & gt; Vorlage. Leider ist die Doc-Seite, die von doxygen aus dem Quellcode generiert wird, keine große Hilfe beim Verständnis der Vorlage. Der Quellcode könnte tatsächlich ein bisschen besser sein:
Die Vorlage array_proxy<>
ist in Matthew Wilsons Buch Imperfect C ++ beschrieben. Die Version, die ich verwendet habe, ist eine abgespeckte Version dessen, was auf der STLSoft-Site ist, so dass ich nicht die ganze Bibliothek einlesen musste. Meine Version ist nicht so portabel, aber das macht es viel einfacher als das, was auf STLSoft ist (das durch eine Menge Portabilitäts-Hoops springt).
Wenn Sie eine Variable wie folgt einrichten:
%Vor% Die Variable myArrayProx
hat viele der STL-Schnittstellen - begin()
, end()
, size()
, Iteratoren usw.
Das array_proxy<>
-Objekt verhält sich also in vielerlei Hinsicht wie ein Vektor (obwohl push_back()
nicht da ist, weil array_proxy<>
nicht wachsen kann - es verwaltet nicht den Speicher des Arrays, sondern wickelt es einfach um in etwas ein wenig näher an einen Vektor).
Eine wirklich nette Sache mit array_proxy<>
ist, dass die Funktion, wenn Sie sie als Funktionsparameter verwenden, die Größe des übergebenen Arrays bestimmen kann, was bei nativen Arrays nicht der Fall ist. Und die Größe des eingepackten Arrays ist nicht Teil des Templatyps, daher ist es ziemlich flexibel zu verwenden.
Ein boost :: iterator_range stellt einen Container zur Verfügung. wie Schnittstelle:
%Vor%Ich war einmal entschlossen, genau dasselbe zu erreichen. Nach ein paar Tagen des Nachdenkens und Versuchens entschied ich, dass es sich nicht gelohnt hat. Ich habe schließlich meinen eigenen benutzerdefinierten Vektor erstellt, der sich wie std :: vectors verhält, aber nur die Funktionalität hat, die ich tatsächlich brauche, wie gebundenes Prüfen, Iteratoren usw.
Wenn Sie immer noch std :: vector verwenden möchten, war die einzige Möglichkeit, an die ich damals denken konnte, die Erstellung eines benutzerdefinierten Zuordners. Ich habe nie eine geschrieben, aber da dies die einzige Möglichkeit ist, die Speicherverwaltung von STL zu steuern, gibt es vielleicht etwas, das dort gemacht werden kann.
Was ist mit Vektor von Zeigern, die auf Ihre zugeordneten Flächenelemente zeigen (reduzierter Speicherverbrauch als Größe von (double *) & lt; sizeof (double))? Ist das in Ordnung für dich?
Es gibt einige Nachteile (primär ist, dass Sie spezielle Prädikate für die Sortierung benötigen), aber auch einige Vorteile, da Sie beispielsweise Elemente löschen können, ohne den tatsächlich zugeordneten Inhalt zu ändern (oder nur eine Anzahl solcher Arrays mit unterschiedlicher Reihenfolge der Elemente ohne) zu den tatsächlichen Werten wechseln).
Es gibt ein gemeinsames Problem aller Lösungen mit std :: vector auf einer gemappten Datei: um den Vektorinhalt in den gemappten Bereich zu "nageln". Dies kann nicht verfolgt werden, Sie können nur nach sich selbst schauen, um etwas nicht zu verwenden, was zu einer erneuten Zuweisung von Vektorinhalt führen könnte. Sei also auf jeden Fall vorsichtig.
Sie könnten mit array_proxy & lt; & gt; gehen, oder werfen Sie einen Blick auf Boost.Array . Es gibt Ihnen size (), front (), back (), at (), operator [] usw. Persönlich würde ich Boost.Array bevorzugen, da Boost sowieso häufiger ist.
Nun, die Vektorvorlage ermöglicht es, einen eigenen Speicherzuordner zu verwenden. Ich habe es nie selbst gemacht, aber ich denke, es ist nicht so schwierig, es auf Ihr Array zu zeigen, vielleicht mit Platzierung neuer Operator ... nur eine Vermutung, schreibe ich mehr, wenn ich versuche und erfolgreich.
Hier ist die Lösung für Ihre Frage. Ich habe das eine ganze Weile versucht, bevor ich eine brauchbare Lösung gefunden habe. Der Nachteil ist, dass Sie die Zeiger nach der Verwendung auf Null setzen müssen, um eine doppelte Freigabe des Speichers zu vermeiden.
%Vor%Alternativ können Sie auch eine Klasse erstellen, die von Vektor erbt und die Zeiger bei der Zerstörung auf Null setzt:
%Vor%Tags und Links arrays c++ vector boost containers