placement new auf stack
-
Dein char-Array könnte sich aber an einer Position befinden, die das nötige Alignment für den Typ T nicht ermöglicht.
-
hmm... stimmt, der anfang nat. nicht^^
würde das hier:
char data[allocating_size*sizeof(T) + std::tr1::alignment_of<T>];nicht schon reichen?
dann müsste ich(muss ich überhaupt?) nur noch mit bissl mit modulo rumspielen, um ne andere startadresse rauszugeben, richtig!?falls das nicht stimmt, würde mir auch nen link reichen - hab gerade keine wirklich gute lektüre zu diesem thema finden können

bb
-
unskilled schrieb:
hmm... stimmt, der anfang nat. nicht^^
würde das hier:
char data[allocating_size*sizeof(T) + std::tr1::alignment_of<T>];nicht schon reichen?
dann müsste ich(muss ich überhaupt?) nur noch mit bissl mit modulo rumspielen, um ne andere startadresse rauszugeben, richtig!?-1 reicht schon. Allerdings gibt es keinen standardkonformen Weg die Ausrichtung eines Zeigers (data) zu ermitteln. Damit hast du keine Rechengrundlage mehr.
-
camper schrieb:
-1 reicht schon.
stimmt^^
camper schrieb:
Allerdings gibt es keinen standardkonformen Weg die Ausrichtung eines Zeigers (data) zu ermitteln. Damit hast du keine Rechengrundlage mehr.
Jopp, ist mir bekannt - macht mir aber nicht so viel aus - gehen tut es in der praxis definitiv - und mir fällt außer "der standard gibt keine garantien darüber" kein grund ein, wieso ichs nciht tun sollte

bb
edit:
hmm...
ich hätt es jz so:template <typename T, std::size_t count> struct stack_allocator { enum { allocating_size = count, allocating_byte = allocating_size*sizeof(T) + std::tr1::alignment_of<T>-1 }; /*...*/ pointer allocate(size_type n, stack_allocator<void, 0>::const_pointer /*hint*/ = 0) { if(n > allocating_size) throw std::bad_alloc(); if(!empty) throw std::bad_alloc(); empty = false; size_type begin = reinterpret_cast<size_type>( data ); size_type offset = begin%std::tr1::alignment_of<T>::value; pointer first = reinterpret_cast<pointer>( begin+offset ); return first; } };allerdings muss ich erst mal nen tr1 update suchen xD
iwann hatte ich das doch mal installiert... *grml*bb
-
unskilled schrieb:
camper schrieb:
-1 reicht schon.
stimmt^^
Was!?
Steh ich auf dem Schlauch? Wieso stimmt das?
-
hmmm - ist wie bei restklassen... nen tollerer vergleich fällt mir gerad nicht ein...
bsp.:
alignment = 4start-adr.: 1
1 2 3 4 -> OK=> +3
start-adr.: 0
0 -> OK=> +0
start-adr.: 2
2 3 4 -> OK=> +2
start-adr.: 3
3 4 -> OK=> +1
max {0, 1, 2, 3} = 3 = 4-1 ;o)
---
bsp.:
alignment = 1
man braucht keine verschiebung, weil jedes element "überall" sein kann ;o)
-> = 0bb
-
Hallo,
Ich bin mir nicht sicher, meine aber in einem der "effective C++" Bücher von Scott Meyers gelesen zu habe, dass placement new mit einem Stack-Objekt "böse" ist. (Wenn ich dran denke und dazu komme, schaue ich heute abend nach.)
Im übrigen frage ich mich ob nicht boost::array oder std::tr1::array deine Anforderungen nicht auch erfüllen?
Gruß
-
camper schrieb:
Für richtige Ausrichtung ist noch zu sorgen:
#include <type_traits> union { char data[sizeof(T)]; typename std::tr1::aligned_storage<sizeof(T),std::tr1::alignment_of<T>::value>::type align; };Hier scheinen einige Leser das
unionübersehen zu haben und überlegen nun, wie man das ohne union schafft.
-
Ich stelle jetzt mal die Gretchenfrage: Welchen Sinn hat placement new mit Stackspeicher?
-
knivil schrieb:
Ich stelle jetzt mal die Gretchenfrage: Welchen Sinn hat placement new mit Stackspeicher?
Speed natürlich.
-
Ja, gegenueber new vielleicht, aber was ist denn mit std::array oder aber das Objekt gleich als lokale Variable anlegen?
-
knivil schrieb:
Ja, gegenueber new vielleicht, aber was ist denn mit std::array oder aber das Objekt gleich als lokale Variable anlegen?
Das ist natürlich besser. Deswegen kann ich meiner Vector-Klasse ja auch mitgeben, ob sie Freispeicher benutzt oder ein Member-Array.
std::array ist keine Alternative, da es die supi vector-Funktionalität nicht hat. also push_back.
-
volkard schrieb:
camper schrieb:
Für richtige Ausrichtung ist noch zu sorgen:
#include <type_traits> union { char data[sizeof(T)]; typename std::tr1::aligned_storage<sizeof(T),std::tr1::alignment_of<T>::value>::type align; };Hier scheinen einige Leser das
unionübersehen zu haben und überlegen nun, wie man das ohne union schafft.
soll so wie heißen, wie ich solls auch mit dem union machen?
in meinen augen ist das bei nem einzelnen element zwar möglich, aber bei mehreren nur platzverschwendung... kann aber auch sein, dass ichs falsch verstanden hab - wie gesagt: hab dazu nix gefunden - allg. ist das tr1 auch 6jahre nach erscheinen noch so schlecht/wenig dokumentiert... :<volkard schrieb:
std::array ist keine Alternative, da es die supi vector-Funktionalität nicht hat. also push_back.
Japp - hatte ich auch weiter oben schon mal geschrieben
Drehleiter schrieb:
Ich bin mir nicht sicher, meine aber in einem der "effective C++" Bücher von Scott Meyers gelesen zu habe, dass placement new mit einem Stack-Objekt "böse" ist. (Wenn ich dran denke und dazu komme, schaue ich heute abend nach.)
das wäre cool : >
bb
-
unskilled schrieb:
in meinen augen ist das bei nem einzelnen element zwar möglich, aber bei mehreren nur platzverschwendung...
Richte doch das ganze Array aus und nicht einzeln jedes Element.
-
unskilled schrieb:
volkard schrieb:
std::array ist keine Alternative, da es die supi vector-Funktionalität nicht hat. also push_back.
Japp - hatte ich auch weiter oben schon mal geschrieben
Yup. Aber knivil hat's ignoriert und zur Gretchenfrage gemacht. Deswegen hab ich's ihm nochmal gesagt.
-
volkard schrieb:
unskilled schrieb:
in meinen augen ist das bei nem einzelnen element zwar möglich, aber bei mehreren nur platzverschwendung...
Richte doch das ganze Array aus und nicht einzeln jedes Element.
Tu ich doch!?
template <typename T, std::size_t count> struct stack_allocator { enum { allocating_size = count, allocating_byte = allocating_size*sizeof(T) + std::tr1::alignment_of<T>-1 }; /*...*/ pointer allocate(size_type n, stack_allocator<void, 0>::const_pointer /*hint*/ = 0) { if(n > allocating_size) throw std::bad_alloc(); if(!empty) throw std::bad_alloc(); empty = false; size_type begin = reinterpret_cast<size_type>( data ); size_type offset = begin%std::tr1::alignment_of<T>::value; pointer first = reinterpret_cast<pointer>( begin+offset ); return first; } };oder gibts hier ein problem?
mit offset berechne ich ja, welchen zeiger ich rausgebe und somit, wo das erste element gespeichert wird...bb
-
Dieser Thread macht mich traurig.
-
volkard schrieb:
Dieser Thread macht mich traurig.
wie wärs, wenn du mal sagen würdest, was du für nen fehler hältst!? bzw. was dir hier nicht passt...
bb
-
unskilled schrieb:
volkard schrieb:
Dieser Thread macht mich traurig.
wie wärs, wenn du mal sagen würdest, was du für nen fehler hältst!?
Alles. Vom Ansinnen, so einen allocator zu bauen übers Ignorieren des union-Tricks über Pseudogretchenfragen über falsche Erinnerungen an Scotty bis zum "!?", wo doch nur ein "?!" passen kann. Es ist ja keiein Ausruf, der als Frage gemein ist, sondern eine Frage, die ausgerufen wird.
-
volkard schrieb:
so einen allocator zu bauen
was würdest du tun? nen c-array mit push back etc. bauen?
selbst, wenn man das hätte müsste man dann noch std::back_inserter spezialisieren...
das scheint mir wesentlich mehr arbeit zu sein...
außerdem ist die allocator-klasse doch genau dazu da...volkard schrieb:
Ignorieren des union-Tricks
ignoriert hab ich ihn nicht - aber ich weiß nicht, in wie fern ich den übernehmen soll... ich kann natürlich nen array mit dem union bauen, also
union_type data[size];- und brauch dann unter umständen nen vielfaches des speichers - du würdest es wohl aber so machen?
am liebsten würde ich ja bevor ich das array deklariere ein dummy-char-array haben, was so viele einträge hat, dass das array danach zwangsläufig am richtigen platz anfängt - allerdings bin ich mir unsicher, ob das hier wirklich richtig ist:#include <type_traits> template <typename T> struct x { enum { count = 123 }; typename std::tr1::aligned_storage<sizeof(T), std::tr1::alignment_of<T>::value>::type alignment; char data[sizeof(T)*count]; };imho würde bei dieser möglichkeit - wie auch bei einem versuch mit union nicht das gewünschte resultat herauskommen...
volkard schrieb:
bis zum "!?", wo doch nur ein "?!" passen kann
nö - bei mir ist !? weniger Frage als ?! ;P
bb