alternative zu placement new
-
Vielleicht nochmals zusammenfassend:
T* ptr = operator new(sizeof(T)); T* ptr = operator new[](5*sizeof(T));
Hiermit wird Speicher allokiert und nicht initialisiert.
new (ptr) T;
Das Placement New initialisiert den Speicher
ptr
, indem eine Instanz an dieser Speicherstelle konstruiert wird. Es können auch Konstruktorargumente fürT
übergeben werden.ptr->~T();
Der explizite Destruktoraufruf ist erforderlich, wenn Zerstörung und Deallokation separat behandelt werden.
operator delete(ptr); operator delete[](ptr);
Der
operator delete
bzw.operator delete[]
gibt den Speicher an der Speicherstelleptr
frei. Hier muss man darauf achten, dass die korrekte Version aufgerufen wird.
-
unskilled schrieb:
und hier kann ich mir dann sicher sein, dass er alignment und padding beachtet:
values = static_cast <ValueType*> (operator new [sizeof(ValueType) * row_count]);
So kannst du
operator new[]
gar nicht aufrufen (siehe mein letzter Post). Eigentlich brauchst du nuroperator new
.Also so:
values = static_cast<ValueType*>(operator new(sizeof(ValueType) * row_count);
Hier sollte kein Problem wegen Alignment entstehen.
Aber du kannst auch einfach den
std::allocator
verwenden.
-
@unskilled,
sizeof
berücksichtig padding und co. Kannst es auch selber testen:struct Foo { int a; char b; }; int main() { std::cout << sizeof(Foo) << std::endl; return 0; }
Kommt bei mir ganz klar 8 dabei raus.
<?xml version="1.0" ?> <off-topic operation="klugscheiss"> <talk-to name="Nexus"> <definition-of value="allokieren">anreden, trösten</definitin-of> <definition-of value="allozieren">zuweisen, bereitstellen</definition-of> <reference type="url">http://faql.de/fremdwort.html#allocate</reference> <commenct>sothis_ hat es zwar nicht nett gesagt, aber recht hat er.</comment> </talk-to> </off-topic>
Und ich will jetzt kein "Nerd" oder ähnliches hören.
Grüssli
-
Danke ^^
Die Zeile hätte schon gereicht - den Rest hatte ich auch so verstanden, nur das konnte ich mir nicht so richtig denken ^^
T* ptr = operator new[](5*sizeof(T));
Aber du kannst auch einfach den std::allocator verwenden.
Hmm... xD Die Idee hätte glatt von mir stammen können... Verdammt ^^ Naja - man lernt ja bei so was wenigstens immer dazu ^^
Kommt bei mir ganz klar 8 dabei raus.
Stimmt - bei mir auch... So gar im x64-Mode oO
bb
-
Dravere schrieb:
Und ich will jetzt kein "Nerd" oder ähnliches hören.
Nene, aber ist gut, dass du meine Gedanken kennst. :p
Aber die ersten beiden Quellen bei Google sagen da etwas Anderes (im Buch hab ich das Wort nicht finden können):
www.duden.de schrieb:
al|lo|kie|ren <zu mlat. allocare>: für einen bestimmten Zweck bereitstellen (bes. Datenv.)
de.wiktionary.org schrieb:
allokieren (Deutsch)
Bedeutungen:
[1] Informatik: (Arbeitsspeicher) belegenSynonyme:
[1] anfordern, belegen
-
Hast du nicht auch die Diskussion auf "de.wiktionary.org" gelesen?
http://de.wiktionary.org/wiki/Diskussion:allokierenIn meinem Duden Zuhause (23. Auflage) befindet sich kein allokieren. Wenn ich im Duden im Web suche, finde ich nur das, was ich schon gesagt habe. Interessanterweise komme ich aber über Goolge auf die Website, welche du per Copy&Paste präsentierst, aber das geht nur über Google
Jedenfalls nach ursprünglicher Bedeutung, macht allozieren deutlich mehr Sinn. Mir ist allerdings nicht klar, ob es so ist, wie in der Dikussion auf Wikitionary erwähnt wird, dass die Informatiker einfach zu dumm waren und das allokieren nun auch in dieser Art in die Sprache aufgenommen wurde.
Naja, wie auch immer, mit allozieren ist man ganz sicher, auf der richtigen Seite
Grüssli
-
gottseidank sind wir keine Compiler die bei nem Tippfehler oder falsch verwendeten Wort einfach aussteigen. Hauptsache ist doch man kann ohne Schwierigkeiten den Text verstehen, und dass keiner hier den armen Speicher trösten will sollte ja bekannt sein
Vllt. kann man sich drauf einigen, neudeutsch "allocieren" zu schreiben - dann kann sich jeder aussuchen wie er das c gern aussprechen möchte.
Oder man verlegt sich aufs englische, so dass die Leute genug damit zu tun haben, ihren eigenen Satzbau zurechtzufrickeln und Kleinigkeiten geduldet werden
-
Decimad schrieb:
Die meisten Implementierungen werden das auch genau so machen.
Aber bedenke folgendes: angenommen T=char, x=1, und die Heap-Implementierung von Compiler Y kann Stücke nicht kleiner als 4 Byte anfordern... Wenn nun der Hersteller von Compiler Y eine Standard-Library Implementierung mitliefert, dann ist es IMO vollkommen OK wenn capacity() nach einem reserve(1) auf einen char-vector als Ergebnis 4 liefert. Grund: es gehen sowieso immer 4 Byte drauf, ob der vector nun nur eins anfordert oder gleich 4. Von daher wäre es ziemlich sinnlos so eine Optimierung zu verbieten. Natürlich könnte man jetzt einwenden dass man ja seinen eigenen allocator an std::vector übergeben könnte (der evtl. problemlos einzelne Bytes allozieren kann ohne Platz zu verschwenden). Allerdings, wenn der Hersteller von Compiler Y schlau ist, dann macht er diese Optimierung auch nur wenn std::allocator verwendet wird
Und nochwas, hätte ich fast vergessen: capacity() darf auch schonmal deswegen nach reserve(x) einen Wert > x melden, weil der vector vor dem reserve(x) ja schon grösser gewesen sein könnte. In diesem Fall schreibt der Standard IIRC sogar vor dass der Speicher NICHT re-alloziert werden soll, die grössere Capacity also erhalten bleiben soll. Das Verhalten was für vector hier vorgeschrieben wird mag zwar seltsam anmuten, ist aber in dem meisten Fällen sehr gut. Natürlich gibt es einige Fälle wo man möchte dass der vector auch mal wieder "schrumpft". In denen muss man dann über diverse Tricks dafür sorgen dass das passiert, z.B. mittels swap(). Das einzige was mir hier abgeht ist eine "shrink" Funktion, so dass man nicht auf umständliche "swap" Tricks angewiesen wäre. Und der Code würde dadurch auch leserlicher (=es wäre einfacher zu sehen was hier passiert, bzw. was der Programmierer bezwecken wollte).
Aber der Standard ist da so frei, dass der vector durchaus auf ein reserve(1) mit einer Kapazität von 20k antworten kann... Und ab da kann sich ja ein standardkonformer Programmierer direkt ausklinken und alle semidynamischen Felder wieder selber kodieren.
Äh. Nö, wieso sollte man das?
Ja, der Standard erlaubt es an vielen Stellen total praxisfremde und bescheuerte Implementierungen zu machen. Nur heisst das noch lange nicht dass ich als Programmierer Rücksicht auf diese Möglichkeit nehmen muss. Der Standard sieht (implizit, dadurch dass er die Klasse definiert) vor, dass std::vector in realen Programmen verwendet wird. Eine Implementierung die das in der Praxis unmöglich macht (bzw. total "unbrauchbar"), z.B. solche hinrissigen Dinge macht wie den zigtausendfachen Speicher anzufordern, bloss weil es erlaubt ist, ist zwar vielleicht dem Buchstaben des Standards nach konform, aber totaler Schwachsinn.
Ich wiederhole mich jetzt, aber wie gesagt, ich nehme auf sowas keine Rücksicht, und ich halte das für eine äusserst realistische und gute Lösung. Geh einfach davon aus dass eine Implementierung dir nicht zu Fleiss irgendwelche Klötze in den Weg werfen wird.BTW: die einzige sinnvolle Alternative zu der Formulierung im Standard wäre IMO eine (u.U. ziemlich lange) Liste von Fällen zu presentieren in denen es erlaubt ist mehr Speicher anzufordern als bei reserve() angegeben wird. Das dumme an solchen Listen ist nur dass man Fälle übersehen kann.
Die Forderung eine praxistaugliche und sinnvolle Implementierung zu wählen ist IMO implizit, muss nicht extra hingeschrieben werden, und wird nach Meiner Erfahrung auch von allen Implementierungen respektiert.
-
ein reserve dass exakt die angeforderten N bytes holt ist idR ein sehr dummes reserve. da man praktisch nie exakt N bytes bekommt sondern immer auf die naechste 2er potenz aligned.
ein
char* p=new char[3];
wird idR nicht 3 byte reservierennur so um darueber zu meditieren