boost::shared_ptr verursacht Crash
-
Hi,
ich habe mir folgende simple Funktion geschrieben, um diese lustige Auto-Release-Funktionalität des shared_ptr zu testen:
void test(void) { boost::shared_ptr<int> iptr,iptr2; int ival=0; iptr.reset(&ival); ival=42; std::cout << "Value: " << *iptr << std::endl; iptr2=iptr; std::cout << "Value " << *iptr2 << std::endl; }Leider funktioniert das nicht, so bald ich die Funktion test() verlasse, schmiert mir das Programm ab - also genau da, wo Boost sich eigentlich um das freigeben der jetzt nicht mehr verwendeten Ressourcen der Shared Pointer kümmern sollte.
Was mache ich falsch?
-
du legst einen shared pointer an, der auf ein int auf dem stack zeigt.
Shared pointer ist zur verwaltung von heap-objekten da.also dann einfcah
int * i = new int(5); boost::shared_ptr<int> sp(i);(am besten aber direkt mit make_shared anlegen).
-
ival ist doch eine Variable auf dem Stack. Diese wird automatisch am Ende freigegeben:
void test() { int ival = 0; ival = 3; } // <--------- Hier wird ival freigegeben
-
Stimmt, das ist die Ursache. Allerdings wirft das eine weitere Frage auf. Ich habe eine Struktur der Form
struct blubb { int irgendwas; int laenge; char data[0]; }Knackpunkt ist hier das data, dieses hat eine dynamische Länge, welche in "laenge" festgelegt wird. D.h. Variablen dieses Typs können nicht mit "new struct blubb" angelegt werden, sondern mit irgend sowas wie "malloc(sizeof(struct blubb)+DataLaenge)". Wie lasse ich sowas von einem shared_ptr verwalten? Schließlich wäre es recht unschön, etwas malloc()iertes mit "delete" löschen zu lassen...
-
Autsch, was für ein Hack.
struct blubb { int irgendwas; std::vector<char> data; }Machs so und lege blubb trotzdem nicht per new an.
-
wieso nicht gleich std::string?
-
Ethon schrieb:
Machs so und lege blubb trotzdem nicht per new an.
Und was hilft mir das, wenn ich es immer noch nicht mit new anlege???
-
diese malloc trickserei ist ziemlich gefährlich und unnötig (wie eben genannt einfach string oder vector nehmen).
Wenn dus aber wirklich willst, kannst du einen shared_ptr per template argument einen custom deleter übergeben, der dann z.B. free statt delete aufruft.
-
daddy_felix schrieb:
wieso nicht gleich std::string?
Weil der Inhalt von data[] eben kein String ist sondern irgend ein anderes, x-beliebiges binäres Datenpaket sein kann.
-
Q schrieb:
diese malloc trickserei ist ziemlich gefährlich und unnötig (wie eben genannt einfach string oder vector nehmen).
Wenn dus aber wirklich willst, kannst du einen shared_ptr pertemplateargument einen custom deleter übergeben, der dann z.B. free statt delete aufruft.
-
und wenn du blubb einen Destruktor spendierst, der den Speicher freigibt?
-
Miguel De La San Rosarios schrieb:
Ethon schrieb:
Machs so und lege blubb trotzdem nicht per new an.
Und was hilft mir das, wenn ich es immer noch nicht mit new anlege???
Und was hilft es dir, wenn du es mit new anlegst?

Bist du Java-Programmierer, oder so?
In C++ legt man so viel wie möglich auf dem Stack ab. Alles was erst zur Laufzeit entschieden wird, wird mit new erstellt.Sag uns doch mal, warum du es mit new anlegen willst, dann können wir dir auch helfen.
-
Miguel De La San Rosarios schrieb:
Ethon schrieb:
Machs so und lege blubb trotzdem nicht per new an.
Und was hilft mir das, wenn ich es immer noch nicht mit new anlege???
Du kannst es mit new anlegen ... nur, wozu ?
-
Miguel De La San Rosarios schrieb:
daddy_felix schrieb:
wieso nicht gleich std::string?
Weil der Inhalt von data[] eben kein String ist sondern irgend ein anderes, x-beliebiges binäres Datenpaket sein kann.
.. womit
stringübrigens sehr wohl zurechtkommt.
-
Da würde ich in dem Fall aber trotzdem zu
vector<char>raten, weil es domain-mäßig eindeutiger ist. In ein paar Jahren weiß dann keiner, was der String da soll.
-
Artchi schrieb:
Da würde ich in dem Fall aber trotzdem zu
vector<char>raten, weil es domain-mäßig eindeutiger ist. In ein paar Jahren weiß dann keiner, was der String da soll.
In wenigen Monaten ...
-
Ethon schrieb:
Autsch, was für ein Hack.
Dieser "Hack" wurde mit C99 im C-Bereich sogar standardisiert. Offiziell ist aber die Variante ohne 0 zwischen den eckigen Klammern, mit [0] ist es aber zumindest nicht verboten, auf Rücksicht auf C89-Compiler. Ob man sowas nun unbedingt auch in C++ benutzen muss, möchte ich allerdings bezweifeln.