Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

21

24.09.2015, 12:07

Danke, dürfte unique_ptr und shared_ptr jetzt verstanden haben, hätte die ohne zu Fragen ziemlich sicher auch falsch benützt.


Mal kurz eine andere Frage. Bist du dir sicher dass du wirklich eine Baumstruktur haben möchtest und keinen Graphen? Je nachdem was du vor hast kann es eben das eine oder das andere sein.


Wirklich sicher bin ich mir nicht, hatte an einen Graphen bis jetzt aber auch noch garnicht gedacht. Kann das jetzt aber auch noch nicht wirklich beantworten, da muss ich mit meiner KI weiter kommen um genau definieren zu können was am besten ist. Bis jetzt kann sie nur sehr einfache Bewegungen und nur mit einer Einheit. Aber das wird jetzt langsam komplexer und dann wird sich auch herausstellen ob ein Baum dafür wirklich richtig war oder ich doch lieber einen Graphen benützen sollte.

22

24.09.2015, 12:07

Kannst du das mal beispielhaft vormachen? Ich hab da ehrlich gesagt gerade mäßig eine Idee, wie man das anstellen könnte.

MfG
Check

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

23

24.09.2015, 14:11

Kannst du das mal beispielhaft vormachen? Ich hab da ehrlich gesagt gerade mäßig eine Idee, wie man das anstellen könnte.

MfG
Check

Was genau meinst du jetzt? Du kannst doch deinen Unique Pointer als Besitzer ansehen welcher vermutlich in irgendeiner Klasse gespeichert wird. Per get() Kannst du dir den Raw Pointer holen und an alle verteilen die das Objekt eben nur benutzen müssen. Keine Ahnung wie sinnvoll das Beispiel ist, aber stell dir vor du implementierst einen Baum per Unique Pointer. Jeder Knoten besitzt Unique Pointer auf die nachfolgenden Knoten. Ein Knoten kann seine Kinder per Raw Pointer zurück geben damit ein Algorithmus darauf arbeiten kann. Der Besitzer der Kindknoten wäre dann der aktuelle Knoten und alle anderen bekommen darauf nur einen Raw Pointer, wie zum Beispiel eben ein Algorithmus der auf dem Baum arbeiten soll.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

24

24.09.2015, 15:44

Ich glaube darum ging's nicht Schorsch. Oder doch?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

25

24.09.2015, 15:53

Ich glaube darum ging's nicht Schorsch. Oder doch?

Er hat zeitgleich mit Shorkan geantwortet weshalb ich nicht davon ausgehe dass es darum ging. Ansonsten würde ja nur noch deine Aussage bleiben dass man zwei Unique Pointer auf den selben Speicher zeigen lassen kann. Das kann man ja einfach per Konstruktor von unique_ptr lösen.

C-/C++-Quelltext

1
2
3
4
5
{
  int *anInteger = new int(42); // Zeiger auf Integer erstellen wobei der Wert des Integers 42 ist
  std::unique_ptr<int> firstUniquePointer(anInteger); // unique_ptr diesen Integer Zeiger verwalten lassen
  std::unique_ptr<int> secondUniquePointer(anInteger); // einen weiteren unique_ptr diesen Integer Zeiger verwalten lassen. Dies tun nun also beide
} // hier knallt es. Der Destruktor von firstUniquePointer gibt den Speicher frei, danach möchte der Destruktor von secondUniquePointer das selbe tun.


Wobei ich mir bei diesem Beispiel gar nicht sicher bin ob es knallt. Normalerweise wären die beiden Unique Pointer aber nicht im selben Scope (sonst bräuchte man ja nur einen) und spätestes bei der Benutzung wird es dann fehleranfällig und wird irgendwann knallen. Aber so könntest du eben zwei Unique Pointer auf einen Speicher zeigen lassen auch wenn das nicht unbedingt sinnvoll ist.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

26

24.09.2015, 17:23

Knallen tuts noch gar nicht, aber danke.
Stand irgendwie auf einem Schlauch.

MfG
Check

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

27

24.09.2015, 17:34

Knallen tuts noch gar nicht, aber danke.

Das meinte ich. Das Beispiel ist an sich etwas doof. Du kannst ja beliebig oft delete auf schon bereinigten Speicher aufrufen und nichts schlimmes passiert. Das Problem ist viel eher dass sobald einer der Unique Pointer gelöscht wird, der Zeiger in allen Unique Pointern freigegeben wird. Wenn du dann darauf zugreifen möchtest gibts halt einen Fehler. Das selbe passiert im Prinzip auch wenn du Raw Pointer weiter gibt. Sobald der Unique Pointer den Speicher frei gibt sind die Raw Pointer eben auch Müll, der Unterschied ist aber dass bei nur einem einzigen Unique Pointer der Besitzer klar ist. Bei mehreren ist das eben nicht klar. Und außerdem wird es schnell Problematisch. Würde ein nicht Besitzer gelöscht dann würde auch der Unique Pointer zerstört, dadurch würde der Speicher freigegeben und der Besitzer zeigt auf etwas was nicht mehr vorhanden ist.
Nur weil es möglich ist ist es also nicht unbedingt sinnvoll.
Beispiel
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

28

24.09.2015, 17:41

Nein, man kann nicht beliebig oft delete auf einem bereinigten Zeiger aufrufen. Es kann jeder Zeit knallen. Jeder der std::unique_ptr gibt den Zeiger am Ende frei. Die doppelte Freigabe ist nicht erlaubt, Undefined Behaviour und führt auch in der Praxis zu Problemen. Das Spektrum der negativen Konsequenzen reicht von einem Absturz an der Stelle über die Freigabe eines anderen Objektes das in der Zwischenzeit zufällig an dem Platz geschoben wurde bis zu einer ganzen Menge anderer Möglichkeiten.

Das Ausprobieren von Code in C++ ist kein Beweis für Fehlerfreiheit.

Nicht umsonst gibt es diverser C++ Tools um die Art Fehler zu finden, die möglicherweise im Programm schlummern und nur darauf warten eines Tages bei einer guten Gelegenheit zuzuschlagen. Clang bietet mit seinem AddressSanitzer eine Möglichkeit "double free"-Bugs aufzuspüren.

Es ist übrigens schon möglich in einem korrekten Programm, dass zwei std::unique_ptr auf die selbe Speicherstelle zeigen. Allerdings nur, wenn einer der std::unique_ptr mit release freigegeben wird. Das ergibt jedoch semantisch überhaupt keinen Sinn.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Spiele Programmierer« (24.09.2015, 17:57)


29

24.09.2015, 17:45

C-/C++-Quelltext

1
2
3
4
5
{
  int *anInteger = new int(42); // Zeiger auf Integer erstellen wobei der Wert des Integers 42 ist
  std::unique_ptr<int> firstUniquePointer(anInteger); // unique_ptr diesen Integer Zeiger verwalten lassen
  std::unique_ptr<int> secondUniquePointer(anInteger); // einen weiteren unique_ptr diesen Integer Zeiger verwalten lassen. Dies tun nun also beide
} 


Ich denke (habe es aber nicht Probiert) das dieser Code-Abschnitt nicht läuft, weil int* != int.

Ich würde Vermuten das Intern für jeden std::unique_ptr<T> ein new aufgerufen wird und jeweils extra speicher Allokiert wird (und eine Kopie des Originals dor hinterlegt wird), somit würde selbst wenn es laufen würde beim löschen des einen es sich in keinster weise auf den anderen auswirken.

Gruß Koschi
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

30

24.09.2015, 17:52

Also ich sehe da keine Zuweisung eines int* zu einem int oder umgekehrt.
Falls dich das verwirrt hat, ein std::unique_ptr<int> verwaltet einen int* und kein int.

Auch mit der Aussage, dass std::unique_ptr neuen Speicher allokiert, liegst du leider falsch. Bei solchen Fragen empfielt sich ein Blick in die Doku. Das es scheinbar funktioniert ist pures Glück. Oder man kann auch sagen Pech, weil so der Fehler nicht auffällt.

Werbeanzeige