Ich hab hier (fremden) Code der mit placement_new std::strings in einen
gemeinsamen Puffer steckt - es ist klar das nur die Member des Strings
selber in dem Placement new buffer landen - der Rest (wenn der String zu
gross wird) landet auf dem Heap
jetzt meldet mir ein Unit-Test + ASAN im Dunstkreis um eine Zuweisung
das hier - unter Ubuntu 21.10 x64/Clang 13.x
wenn eine Zuweisung-Zeile aktiv ist
und auch nur wenn ich nicht mit einem const char* zuweise
1
std::string& ziel bezieht sich auf einen std::string irgendwo im placement new buffer
2
3
1.
4
ziel = "blub"; // keine Meldung
5
ziel.assign("blub"); // keine Meldung
6
ziel = std:string("blub"); // keine Meldung
7
8
2.
9
ziel.assign( chars, chars + char_count ); // Leak
10
11
3.
12
ziel = std::string(chars, chars + char_count); // Leak
mein Kollege meinte das placement new und std::string nicht kompatible
sind
was für mich ein Ammenmärchen aus den Zeiten von Drachen und Rittern ist
ich denke irgendwie ist die Quelle "beschädigt" oder sowas
mein Test-Code der erstmal zeigt das placement new auf std::string nicht
per se ein Problem ist
1
#include <string>
2
3
int main()
4
{
5
{
6
std::string a;
7
8
a = "hallo";
9
a = "bert";
10
}
11
12
{
13
std::string* b = new std::string();
14
b->operator=("hallo");
15
b->operator=("bert");
16
delete b;
17
}
18
19
{
20
char buffer[sizeof(std::string)]{};
21
22
std::string* c = new (buffer) std::string();
23
24
c->operator=("hallo");
25
c->operator=("bert");
26
c->assign(std::string("uwe"));
27
28
c->~basic_string();
29
}
30
31
{
32
char buffer[sizeof(std::string)]{};
33
34
std::string* c = new (buffer) std::string();
35
36
std::string& rc = *c;
37
38
rc = "hallo";
39
rc = "bert";
40
rc = std::string("uwe");
41
rc.assign(std::string("uwe"));
42
43
c->~basic_string();
44
}
45
}
irgendjemand einen Idee - nach was ich schauen könnte? Warum z.B. die
const char Zuweisung "geht"
Deine Tests schreiben wohl alle in den internen Buffer von std::string
(Stichwort SSO). Ich bin schon ziemlich sicher dass placement new über
einen std::string ein Leak erzeugt sofern der String am Heap liegt.
Es wird ja
1.) Kein Dtor aufgerufen
2.) Wird der Ctor vom neuen std::string Objekt wohl kaum prüfen ob er
"nicht eh schon was alloziert" hat...
Vincent H. schrieb:> (Stichwort SSO). Ich bin schon ziemlich sicher dass placement new über> einen std::string ein Leak erzeugt sofern der String am Heap liegt.
und bist zu wenig eindeutig das man versteht welchen Teil du vom String
meinst - die std::string Instanz selbst oder den zusätzlich verwalteten
Puffer wenn der String zu gross wird (falls es Small-String Optimization
gibt)
bei der string instanz selbst sollten während der Zuweisungen keine
ctor/dtor Aktionen statt finden (wo für?)
cppbert schrieb:> mein Kollege meinte das placement new und std::string nicht kompatible> sind> was für mich ein Ammenmärchen aus den Zeiten von Drachen und Rittern ist
Würde ich auch so sehen.
> irgendjemand einen Idee - nach was ich schauen könnte? Warum z.B. die> const char Zuweisung "geht"
std::string kann höhere Anforderungen an das alignment haben. Während
ein char[] wahrscheinlich an jeder Byte-Grenze ausgerichtet sein kann,
wird das für std::string nicht gelten.
Torsten R. schrieb:> cppbert schrieb:>>> mein Kollege meinte das placement new und std::string nicht kompatible>> sind>> was für mich ein Ammenmärchen aus den Zeiten von Drachen und Rittern ist>> Würde ich auch so sehen.
Danke
>> irgendjemand einen Idee - nach was ich schauen könnte? Warum z.B. die>> const char Zuweisung "geht">> std::string kann höhere Anforderungen an das alignment haben. Während> ein char[] wahrscheinlich an jeder Byte-Grenze ausgerichtet sein kann,> wird das für std::string nicht gelten.
der String selbst ist mit alignof so wie auch der Kompiler/new es auf
dem Stack/Heap machen würden alligned
cppbert schrieb:> mein Kollege meinte das placement new und std::string nicht kompatible> sind
wen dem so waere, dann wuerde std::vector<std::string> nicht
funktionieren.
> mein Test-Code der erstmal zeigt das placement new auf std::string nicht> per se ein Problem ist
der zeigt auch nicht den code mit dem du ein problem hast.
Cheers, Roger
cppbert schrieb:> bei der string instanz selbst sollten während der Zuweisungen keine> ctor/dtor Aktionen statt finden (wo für?)
Ah Pardon. Ich hab grad erst gesehn dass der String in einen char Buffer
gelegt wird. Meine erste Deutung war irgendwie std::string über
std::string (was mit placement new ebenfalls ginge).
Bitte mein erstes Posting ignorieren.
cppbert schrieb:> und bist zu wenig eindeutig
Dein Post, mit dem du den Thread gestartet hast, ist auch kein
Musterbeispiel für Eindeutigkeit. Ich kann daraus nicht wirklich
ableiten, was bei dir funktioniert und was nicht.
Wenn ich dich richtig verstehe
cppbert schrieb:> mein Test-Code der erstmal zeigt das placement new auf std::string nicht> per se ein Problem ist
funktioniert das Beispiel. Was funktioniert nicht?
Roger S. schrieb:> cppbert schrieb:>> mein Kollege meinte das placement new und std::string nicht kompatible>> sind>> wen dem so waere, dann wuerde std::vector<std::string> nicht> funktionieren.
oder auch einfach new std::string() - der Unterschied zu placement new
ist nur das er implicit mit sizeof(Type) allokiert - thats it
>> mein Test-Code der erstmal zeigt das placement new auf std::string nicht>> per se ein Problem ist>> der zeigt auch nicht den code mit dem du ein problem hast.
an der Stelle passiert nur eine Zuweisung - der Initialisierungs-Code
ist zu umfangreich um den hier einzustellen - deswegen meine Hoffnung
das einer von euch eine (wilde) Idee hat
es passiert scheinbar nur wenn std::string(chars, chars + char_count)
mit im Spiel ist - und die Daten kommen aus einer deserialisierung
#if 0 // alles ohne leak
// mit/ohne const kein leak
std::string blub = "blub";
ziel = blub;
ziel.assign( blub );
ziel.assign( std::string(blub) );
ziel.assign( blub.begin(), blub.end() );
ziel.assign( std::string(blub.begin(), blub.end() ) );
ziel = "blub";
ziel.assign( "blub" );
ziel.assign( std::string("blub") );
#else // leaken beide
const std::string x = std::string(chars, chars + char_count);
ziel = x;
//ziel.assign(x);
#endif
und die ganzen Zuweisungen landen wegen dem const eh alle in einem
Kopieraktion
deswegen ist mir so unklar wo da der Fehler herkommen soll
oder mein chars-Pointer+chars+chars_count ist irgendwie korrupt
muss da der char-Ptr aligned sein?
der Unit-Test bringt auch ordentlich Last mit ein paar tausend
Allokationen/Zuweisungen
dachte das man damit irgendwelche Korruptionen doch auch erkennen
muesste (über die Zeit) - aber nur ASAN meldet was - das System laeuft
scheinbar stabil
Roger S. schrieb:> Immer noch nicht der ganze code. Rufst du auch den destructor des> ziel> strings auf, so wies du bei dem 'funktionierenden' Beispiel tust?
ja das mache ich - und der ganze Code sind ein paar hundert Zeilen -
wenn ich den so reduziere das ich es hier zeigen kann kommt sowas raus
wie in meinem Beispiel
cppbert schrieb:> ja das mache ich - und der ganze Code sind ein paar hundert Zeilen -> wenn ich den so reduziere das ich es hier zeigen kann kommt sowas raus> wie in meinem Beispiel
Dann mach es, moeglicherweise wirst du dann feststellen dass das Problem
nicht dort liegt wo du es vermutest. Ich geh davon aus dass char_count
groesser als das SSO limit Deiner string implementation ist, und es
daher einen Unterschied macht ob der Destructor des strings aufgerufen
wird. Das ist in etwa das was ich anhand der gezeigten Schnippsel
wahrsagen kann.
cppbert schrieb:> mh schrieb:>> Was wir dir sagen wollen:>> https://stackoverflow.com/help/minimal-reproducible-example>> wenn ich das Szenario so weit eindampfe - siehe Beispielcode vom> Eingangspost passiert der Fehler nicht mehr - sind ~500 Zeilen Code> direkt beteiligt
Das ist unwahrscheinlich. Und dein Beispiel im Eingangspost hat nichts
mit dem mimimalen Beispiel zu tun, das in dem Link beschrieben wird.
Dein Beispiel besteht aus 4 seperaten Teilen, von denen keins den Fehler
reproduziert.
mh schrieb:> cppbert schrieb:>> mh schrieb:>>> Was wir dir sagen wollen:>>> https://stackoverflow.com/help/minimal-reproducible-example>>>> wenn ich das Szenario so weit eindampfe - siehe Beispielcode vom>> Eingangspost passiert der Fehler nicht mehr - sind ~500 Zeilen Code>> direkt beteiligt>> Das ist unwahrscheinlich. Und dein Beispiel im Eingangspost hat nichts> mit dem mimimalen Beispiel zu tun, das in dem Link beschrieben wird.> Dein Beispiel besteht aus 4 seperaten Teilen, von denen keins den Fehler> reproduziert.
das Beispiel war nur um zu zeigen das placement new in den Situationen
völlig normal funktioniert - den Fehler kann man einfach mit weglassen
vom dtor provozieren - ABER ich hab es jetzt doch schon gefunden
das ganze placement-newing ist unter einer komischen alloc/free API
verborgen zu der es auch eine automatisch aufräumende Variante gibt
der Unit-Test nutzt die manuelle Variante (was falsch ist, wovon ich
aber ausgegangen bin) und es fehlte einfach mitten drin in den Tests ein
free-Aufruf an diese API :/
ASAN/LSAN hat für den Leak-Ursprung auch nur so eine unsymbolize Ausgabe
gemacht - das hat mich irritiert weil ich sonst immer schön die
Quelltexttzeilen usw. bekommen
Kurzum: komplett an der falschen Stelle gesucht weil ich von einer
anderen Grundlage ausgegangen bin
Danke für eure Teilnahme an dem Spass :)
cppbert schrieb:> Kurzum: komplett an der falschen Stelle gesucht weil ich von einer> anderen Grundlage ausgegangen bin
Kurz gesagt: Hättest du das minimale Beispiel gebaut, hättest du den
Fehler gefunden. Ein "minimales compilierbares Fehler reproduzierendes
Beispiel" ist nicht nur der beste Weg nach Hilfe zu Fragen, es ist auch
ein sehr guter Weg den Fehler selbst zu finden.
mh schrieb:> Kurz gesagt: Hättest du das minimale Beispiel gebaut, hättest du den> Fehler gefunden. Ein "minimales compilierbares Fehler reproduzierendes> Beispiel" ist nicht nur der beste Weg nach Hilfe zu Fragen, es ist auch> ein sehr guter Weg den Fehler selbst zu finden.
Der OP hatte uns darum gebeten, eine seiner Annahmen zu verifizieren und
dabei sein Problem erläutert.
Das Reduzieren eines Problems auf ein Minimum kann schon mal mehrere
Tage dauern. Was spricht dagegen, grundsätzliche Annahmen vorher schon
mal zu verifizieren?
mh schrieb:> cppbert schrieb:>> Kurzum: komplett an der falschen Stelle gesucht weil ich von einer>> anderen Grundlage ausgegangen bin>> Kurz gesagt: Hättest du das minimale Beispiel gebaut, hättest du den> Fehler gefunden. Ein "minimales compilierbares Fehler reproduzierendes> Beispiel" ist nicht nur der beste Weg nach Hilfe zu Fragen, es ist auch> ein sehr guter Weg den Fehler selbst zu finden.
Ich weiß doch das ein fehlender dtor-Aufruf mit einem placement new
std::string ein Leak erzeugen (kann) das wäre keine neue Erkenntnis
gewesen
aber du hast definitiv recht weil die ASAN/LSAN Meldung wäre dann so
schön identisch gewesen und ich wäre wohl schneller auf die Idee
gekommen an der richtigen Stellen zu schauen
cppbert schrieb:> mh schrieb:>> cppbert schrieb:>>> Kurzum: komplett an der falschen Stelle gesucht weil ich von einer>>> anderen Grundlage ausgegangen bin>>>> Kurz gesagt: Hättest du das minimale Beispiel gebaut, hättest du den>> Fehler gefunden. Ein "minimales compilierbares Fehler reproduzierendes>> Beispiel" ist nicht nur der beste Weg nach Hilfe zu Fragen, es ist auch>> ein sehr guter Weg den Fehler selbst zu finden.>> Ich weiß doch das ein fehlender dtor-Aufruf mit einem placement new> std::string ein Leak erzeugen (kann) das wäre keine neue Erkenntnis> gewesen
Und wie sollen wir feststellen, dass ein dtor fehlt? Aus deinem Post
wird nichtmal deutlich, ob im realen Programm, das den Fehler enthält,
Raw-Pointer vorkommen.
Torsten R. schrieb:> Das Reduzieren eines Problems auf ein Minimum kann schon mal mehrere> Tage dauern. Was spricht dagegen, grundsätzliche Annahmen vorher schon> mal zu verifizieren?
Wenn es mehrere Tage dauert das Problem zu minimieren ist das halt so.
Die Arbeit kann man ihm nicht abnehmen. Wenn er eine konkrete Frage hat
ist das was anderes.
mh schrieb:>> Ich weiß doch das ein fehlender dtor-Aufruf mit einem placement new>> std::string ein Leak erzeugen (kann) das wäre keine neue Erkenntnis>> gewesen>> Und wie sollen wir feststellen, dass ein dtor fehlt? Aus deinem Post> wird nichtmal deutlich, ob im realen Programm, das den Fehler enthält,> Raw-Pointer vorkommen.
was hat das jetzt mit Raw-Pointern zu tun?
der sich im std::string befindliche Point auf den Heap-String wurde
nicht aufgeräumt weil der dtor des std::strings nicht explizit
aufgerufen wurde
das ist aber alles unter einer riesigen API verborgen und schlussendlich
ist ein Test eben nicht Test-Konform und keinem ists aufgefallen
mh schrieb:> Torsten R. schrieb:>> Das Reduzieren eines Problems auf ein Minimum kann schon mal mehrere>> Tage dauern. Was spricht dagegen, grundsätzliche Annahmen vorher schon>> mal zu verifizieren?>> Wenn es mehrere Tage dauert das Problem zu minimieren ist das halt so.> Die Arbeit kann man ihm nicht abnehmen. Wenn er eine konkrete Frage hat> ist das was anderes.
dafür war das Problem dann aber doch nicht groß genug - Denkanstoß
reicht oft auch schon aus
aber habt ihr vielleicht noch einen Tip wie ich die ASAN/LSAN Meldung
noch verbessern könnten
main.cpp
1
#include <string>
2
3
int main()
4
{
5
{
6
std::string* s = new std::string();
7
s->operator=("wir brechen mal ordentlich aus der der small string optimization aus!");
8
//delete s;
9
}
10
11
{
12
char buffer[sizeof(std::string)]{};
13
std::string* s = new (buffer) std::string();
14
s->operator=("wir brechen mal ordentlich aus der der small string optimization aus!");
cppbert schrieb:> was hat das jetzt mit Raw-Pointern zu tun?> der sich im std::string befindliche Point auf den Heap-String wurde> nicht aufgeräumt weil der dtor des std::strings nicht explizit> aufgerufen wurde
Und warum wurde der dtor nicht aufgerufen? Weil ein Raw-Pointer benutzt
wurde, um den string zu speichern.
mh schrieb:> cppbert schrieb:>> was hat das jetzt mit Raw-Pointern zu tun?>> der sich im std::string befindliche Point auf den Heap-String wurde>> nicht aufgeräumt weil der dtor des std::strings nicht explizit>> aufgerufen wurde>> Und warum wurde der dtor nicht aufgerufen? Weil ein Raw-Pointer benutzt> wurde, um den string zu speichern.
placement new und Smart-Pointer macht recht wenig Sinn
der std::string wirde mit placement new in einen grossen Puffer
eingebettet
das Leak kommt von dem internen String auf dem Heap den std::string
verwaltet wenn der die String die Small-String Optimization sprengt und
am Ende der dtor nicht aufgerufen wird - das geht nicht mit einem
Smart-Pointer - oder macht eben absolut keinen Sinn
Es ist eine dynamisches Type-System das zur Laufzeit aus
Type-Hierarchien schnelle/effiziente Datenspeicher erzeugen kann - und
diese API wurde im Test nicht richtig verwendet - davon bin ich aber
ausgegangen weil es sonst einfach zu unsicher ist
cppbert schrieb:> placement new und Smart-Pointer macht recht wenig Sinn>> der std::string wirde mit placement new in einen grossen Puffer> eingebettet> das Leak kommt von dem internen String auf dem Heap den std::string> verwaltet wenn der die String die Small-String Optimization sprengt und> am Ende der dtor nicht aufgerufen wird - das geht nicht mit einem> Smart-Pointer - oder macht eben absolut keinen Sinn
Da solltest du nochmal drüber nachdenken. Was genau spricht gegen einen
Smart-Pointer?
mh schrieb:> cppbert schrieb:>> placement new und Smart-Pointer macht recht wenig Sinn>>>> der std::string wirde mit placement new in einen grossen Puffer>> eingebettet>> das Leak kommt von dem internen String auf dem Heap den std::string>> verwaltet wenn der die String die Small-String Optimization sprengt und>> am Ende der dtor nicht aufgerufen wird - das geht nicht mit einem>> Smart-Pointer - oder macht eben absolut keinen Sinn>> Da solltest du nochmal drüber nachdenken. Was genau spricht gegen einen> Smart-Pointer?
ich bin mir nicht sicher ob du technisch verstehst was die Leak-Ursache
ist
der grosse Puffer ist schlussendlich einfach ein std::vector da braucht
es keinen Smart-Pointer
und wenn du 100 Variablen
std::strings/ints/struct/arrays/vektoren/doubles die teilweise selbst
hierarchisiert sind kompakt in den Puffer (mit entsprechendem alignment)
anordnen willst um eben keine 100 Einzelallokationen zu haben dann
kannst du hier nirgends einen Smart-Pointer einbauen - der macht den
ganzen placement new Vorteil vollständig zunichte - es geht um hohe
Flexibilität zur Laufzeit und Gigabytes an Daten im Simulationsumfeld
cppbert schrieb:> ich bin mir nicht sicher ob du technisch verstehst was die Leak-Ursache> ist>> der grosse Puffer ist schlussendlich einfach ein std::vector da braucht> es keinen Smart-Pointer
Der große Puffer ist ja auch nicht dein Problem, er leakt nicht. Es geht
um den String in deinem Beispiel. Du benutzt einen Raw-Pointer, der auf
diesen String zeigt. Der dtor dieses Strings wird nicht aufgerufen.
Verstehst du das Problem? Könnte ein Smart-Pointer, der automatisch den
dtor aufruft das Problem lösen?
mh schrieb:> cppbert schrieb:>> ich bin mir nicht sicher ob du technisch verstehst was die Leak-Ursache>> ist>>>> der grosse Puffer ist schlussendlich einfach ein std::vector da braucht>> es keinen Smart-Pointer>> Der große Puffer ist ja auch nicht dein Problem, er leakt nicht. Es geht> um den String in deinem Beispiel. Du benutzt einen Raw-Pointer, der auf> diesen String zeigt.
ja, damit an den Speicherbereich des std::string komme - der irgendwo in
dem placement new buffer ist
> Der dtor dieses Strings wird nicht aufgerufen.> Verstehst du das Problem? Könnte ein Smart-Pointer, der automatisch den> dtor aufruft das Problem lösen?
eher nicht - weil dazu muss der Smart-Pointer doch die Kontrolle über
den std::string haben - was er aber nicht haben kann weil dieser
eingebettet in dem placement new buffer ist (mit vielen anderen
Variablen zusammen)
wenn man placement new verwendet verliert man jeglichen Automatismus
bezüglich aufräumen - ausser eben der komplette placement Puffer selbst
hier ein Beispiel was das System macht
durch die dynamische Typ-Beschreibung ist klar das mein Typ
aus einem Double, Int8, String und besteht (die intern abbildung davon
ist ein echter double, int8_t und std::string) - Struct, Arrays/Vektoren
verwenden
eigenen Abbildungen die zur Laufzeit aber dem Verhalten von struct,
std::array und std::vector entsprechen (aber eben nicht auf diesen
basieren)
dann wird in etwa das gemacht
(alles zur Laufzeit)
1. placement_new_buffer_size = summe über alle Typen.sizeof() +
alignment beachten
2. std::vector<uint8_t> buffer(palcement_new_buffer_size);
3. die Laufzeit-Typen die initalisierung benötigen z.B. std::string oder
std::vector werden durch das Type-System in dem buffer initialisiert
jetzt ist im buffer der Aufbau
---
0: sizeof(double) bytes 8
8: sizeof(int8_t) bytes 1
10: sizeof(std::string(der hat selbst einen Zeiger)) bytes (~30-40)
---
der buffer sieht jetzt exakt so aus wie ein C++ struct der Art im
Speicher
- nur das es eben alles dynamisch erzeugt wurde
da gibt es jetzt keinen Pointer die zu verwalten sind
und irgendwas wie std::vector<std::any<std::unique_ptr<...>>>>
würde die Performanz und Kompatkanforderung völlig zerstören
wo siehst du da eine Maglichkeit einen Smart-Pointer ein zu bauen
1. den std::string kann und will ich nicht aendern
2. die Elemente Einzel auf den Heap zu stellen ist sinnfrei
3. ein Smart-Pointer !darf hier nicht deleten! - der dürfte maximal den
dtor
Aufrufen - weil der buffer ja jemand anderem gehört
der dtor wird vom dynamischen Type-System für alle Kinder in dem Puffer
gezielt aufgerufen - weil die ein Out-of-Scope gehen gar nicht
mitbekommen
- und genau das hat in dem Unit-Test gefehlt - das darüberliegende
System macht das automatisch - aber das hat der Unit-Test Entwickler
leider nicht verwendet
RAII und placement new kombinieren sich nicht gut - oder du kannst
dir placement new sparen
alle Objekte die du in placement new Puffer steckst können nicht mehr
ohne manuellen Aufwand detored werden (deren internen Objekt-Members
werden aber durch den äußeren dtor Aufruf wie üblich weiter verarbeitet)
cppbert schrieb:> [...]> eher nicht - weil dazu muss der Smart-Pointer doch die Kontrolle über> den std::string haben> [...]
Je, er muss die Kontrolle haben, den Destruktor aufzurufen. Als Hinweis:
mh schrieb:> cppbert schrieb:>>> [...]>> eher nicht - weil dazu muss der Smart-Pointer doch die Kontrolle über>> den std::string haben>> [...]>> Je, er muss die Kontrolle haben, den Destruktor aufzurufen. Als Hinweis:> template<> class T,> class Deleter = std::default_delete<T>>> class unique_ptr;
Selbst wenn man den Deleter ersetz wird der dtor vom unique_ptr trotzdem
nicht automatisch aufgerufen weil der unique_ptr nicht out of scope
geht, sollte dieser im placement new buffer liegen
und um von aussen mit einem nur-dtorendem pseudo Smartpointer in den
puffer hinnein zu zeigen braucht man ja wieder einen vector oder
aehnliches um diesen oder mehreren smart pointer einen scope zu geben
und der muss auch noch typesafe sein d.h. ein simple vector mit
smartpointern reicht nicht, und das ist wieder alles andere als kompakt
cppbert3 schrieb:> elbst wenn man den Deleter ersetz wird der dtor vom unique_ptr trotzdem> nicht automatisch aufgerufen weil der unique_ptr nicht out of scope> geht, sollte dieser im placement new buffer liegen
Du sollst nicht den unique_ptr in den Buffer stecken.
cppbert3 schrieb:> und um von aussen mit einem nur-dtorendem pseudo Smartpointer in den> puffer hinnein zu zeigen braucht man ja wieder einen vector oder> aehnliches um diesen oder mehreren smart pointer einen scope zu geben> und der muss auch noch typesafe sein d.h. ein simple vector mit> smartpointern reicht nicht, und das ist wieder alles andere als kompakt
Was soll jetzt dein "pseudo Smartpointer" sein?
Und wenn es jemanden gibt, der den richtigen Destruktor aufrufen kann,
gibt es auch einen möglichen Owner für einen Smart-Pointer. Irgendwer
muss sich ja merken, was in dem Speicher steht.
mh schrieb:> Was soll jetzt dein "pseudo Smartpointer" sein?
Ein smartpointer der nicht deleted sondern nur den dtor Aufruft
> Und wenn es jemanden gibt, der den richtigen Destruktor aufrufen kann,> gibt es auch einen möglichen Owner für einen Smart-Pointer. Irgendwer> muss sich ja merken, was in dem Speicher steht.
Wie gesagt das gibt es auf einer höheren Ebene, ist nur kein
"Smartpointer" aber trotzdem RAII, d.h. also auch Exception Safe usw.
Aber der Unit Tester hat die non public API getestet, was er gar nicht
durfte
weiter unten könnte man das auch sicherer machen, aber ich würde das
"aufräumen" in dem zusammenhang trotzdem nicht als Smartpointer
bezeichnen - finde ich ein wenig irreführend