smart pointer
-
Ich bin auf der Suche nach dem richtigen Smart Pointer:
Ich hab eine Menge von Punkten, die ich bisher als std::vector<std::vector<double> > "allpoints" gespeichert hab. Zusätzlich hab ich eine Datenstruktur, die die Punkte speichern soll. Es sollen allerdings aus Speicherplatzgründen, keine Kopien der Punkte erstellt werden. Bisher hab ich diese Punkt-Pointer als std::vector<double>* in der Datenstruktur abgelegt. Das geht solange gut, bis man Punkte zu "allpoints" hinzufügt und der std::vector neuen Speicher allokiert...
Ich suche jetzt den richtigen Smart Pointer, der die Anzahl der Referenzen zählt, sodass ich die Punktemenge als std::vector<XY<std::vector<double> > > speicher kann und die Punkte in der Datenstrutkur entsprechend als XY<std::vector<double> >. Was muss ich da nehmen (C++11 ist in Ordnung).
-
std::shared_pointer
-
Du meinst std::shared_ptr ?
thx
-
Bist du sicher, dass du geteilten Besitz hast?
Oder kannst du im einen Container einfach die Punkte als Werte abspeichern, und im anderen normale Zeiger darauf?
-
Alle Punkte, die in meiner eigenen Datenstruktur vorkommen, existieren auch im Sammelcontainer.
Gibt es da etwas besseres als shared_ptr?
-
Wie wärs wenn du einfach direkt allpoints benutzt? Bzw. einen Pointer/Referenz da drauf.
-
Wer besitzt die Punkte? Derjenige hält sie als Objekte. Die Container, die nur darauf verweisen, halten rohe Zeiger.
Kein Grund für
shared_ptr
...
-
Es kommt drauf an, wieso du die Daten mehrmals speicherst bzw. von mehreren Orten Zugriff drauf haben willst, sie aber nicht duplizieren willst.
Wenn du später so Späße wie std::vector<std::shared_ptr<double>> und MyDataStructure<std::shared_ptr<double>> hast, dann sieht das erstmal ziemlich nach Overhead aus. Shared_ptr kostet mit seiner Referenzzählung ja auch etwas.
Eventuell würde sich eine Funktion/ethode zum Synchronisieren beider Datenstrukturen, die periodisch oft aufgerufen wird, auch lohnen.
-
Nexus schrieb:
Wer besitzt die Punkte? Derjenige hält sie als Objekte. Die Container, die nur darauf verweisen, halten rohe Zeiger.
Kein Grund für
shared_ptr
...So hab ich es bisher auch gemacht. Problematisch wird es, wenn ich nun neue Punkte hinzufüge und der std::vector, der alle Punkte enthält, wachsen muss: Dann werden alle Zeigen in meinen Datenstrukturen ungültig, deshalb dachte ich, ein Smartpointer wäre besser.
@Skym0sh0:
Ich speichere keine Skalare sondern niedrig-dimensionale Punkte (ich denke, typisch wären vielleicht 10 Dimensionen, maximal jedoch sowas wie 20). Wie viel verbraucht denn ein shared_ptr? Eine Speicheradresse für die Daten + eine für den Zähler + ein geteilten Zähler. Bei 10 Dimensionen ist der Overhead noch erträglich. Einsparen könnte man auch etwas, wenn sowas wie ein Dynarray (http://www.c-plusplus.net/forum/311821-full) benutzt.
-
Ramanujan schrieb:
So hab ich es bisher auch gemacht. Problematisch wird es, wenn ich nun neue Punkte hinzufüge und der std::vector, der alle Punkte enthält, wachsen muss: Dann werden alle Zeigen in meinen Datenstrukturen ungültig, deshalb dachte ich, ein Smartpointer wäre besser.
Versuchs mit
std::deque
, dessenpush_back()
invalidiert Referenzen und Zeiger nicht. Beim Einfügen in der Mitte oder Löschen musst du aber nach wie vor aufpassen.Wenn du unbedingt Smart-Pointer brauchen solltest, wäre immer noch
std::unique_ptr
vorzuziehen.Ramanujan schrieb:
Wie viel verbraucht denn ein shared_ptr? Eine Speicheradresse für die Daten + eine für den Zähler + ein geteilten Zähler.
Dazu kommt das Deleter-Objekt. Einiges kann zwar zusammen allokiert werden, braucht aber natürlich trotzdem Speicher. Vergiss aber auch nicht den Rechenzeit-Overhead von
std::shared_ptr
, der durch Reference-Counting und Multithreading entsteht. Aber wie gesagt, hier istshared_ptr
ohnehin nicht angebracht.