<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Allokationen zentralisieren]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich möchte eine MemoryManager Klasse schreiben, die Heap Allokationen zentralisiert. D.h. man kann sollte im Code nirgends mehr new aufrufen, sondern alle Allokationen nur noch per MemoryManager Klasse vornehmen. Den allokierten Blöcken will ich Metainfos wie z.B. einen beschreibenden String anhängen (hat vor allem Debuggründe).</p>
<p>Jetzt frage ich mich, wie ich das am besten implementiere.<br />
Meine 2 ersten Ideen waren:<br />
1. Templates, also vielleicht sowas:</p>
<pre><code class="language-cpp">Foo* f = MemoryMng.allocate&lt;Foo&gt;(&quot;my foo object&quot;);
char* c = MemoryMng.allocateArray&lt;char&gt;(1000);
</code></pre>
<p>Das Problem das ich hier habe: Wie übergebe ich Werte an Konstruktoren von Klassen? Also wenn Foo zb. 3 Paramter kriegt, wie übergebe ich die an den Foo Ctor?</p>
<p>2. Wegen der Ctor Argument Problematik kam ich auf Ansatz 2: placement new:</p>
<pre><code class="language-cpp">Foo* f = MemoryMng.allocate(sizeof(Foo), &quot;my foo object&quot;); // allokiert sizeof(foo) bytes. Kein Ctor Aufruf!
f = new (f) Foo(a, b, c);
</code></pre>
<p>Das sollte so ja klappen, oder? Muss ich beim placement new irgendwas beachten bzgl. Alignment?</p>
<p>Was findet ihr besser bzw. gäbe es noch eine bessere Lösung?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/285919/allokationen-zentralisieren</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 12:24:23 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/285919.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 29 Apr 2011 19:37:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Allokationen zentralisieren on Fri, 29 Apr 2011 19:37:23 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich möchte eine MemoryManager Klasse schreiben, die Heap Allokationen zentralisiert. D.h. man kann sollte im Code nirgends mehr new aufrufen, sondern alle Allokationen nur noch per MemoryManager Klasse vornehmen. Den allokierten Blöcken will ich Metainfos wie z.B. einen beschreibenden String anhängen (hat vor allem Debuggründe).</p>
<p>Jetzt frage ich mich, wie ich das am besten implementiere.<br />
Meine 2 ersten Ideen waren:<br />
1. Templates, also vielleicht sowas:</p>
<pre><code class="language-cpp">Foo* f = MemoryMng.allocate&lt;Foo&gt;(&quot;my foo object&quot;);
char* c = MemoryMng.allocateArray&lt;char&gt;(1000);
</code></pre>
<p>Das Problem das ich hier habe: Wie übergebe ich Werte an Konstruktoren von Klassen? Also wenn Foo zb. 3 Paramter kriegt, wie übergebe ich die an den Foo Ctor?</p>
<p>2. Wegen der Ctor Argument Problematik kam ich auf Ansatz 2: placement new:</p>
<pre><code class="language-cpp">Foo* f = MemoryMng.allocate(sizeof(Foo), &quot;my foo object&quot;); // allokiert sizeof(foo) bytes. Kein Ctor Aufruf!
f = new (f) Foo(a, b, c);
</code></pre>
<p>Das sollte so ja klappen, oder? Muss ich beim placement new irgendwas beachten bzgl. Alignment?</p>
<p>Was findet ihr besser bzw. gäbe es noch eine bessere Lösung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056257</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056257</guid><dc:creator><![CDATA[Alloka]]></dc:creator><pubDate>Fri, 29 Apr 2011 19:37:23 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Fri, 29 Apr 2011 19:47:00 GMT]]></title><description><![CDATA[<p>Ich würde mich bei so einer Klasse an std::allocator&lt;&gt; orientieren (falls du das noch nicht kennst - das verwenden die STL-Container, um Speicher zu reservieren).</p>
<p>Außerdem kann man benutzerdefinierte operator new() mit beliebigen Parametern definieren, so daß dann sowas möglich ist:</p>
<pre><code class="language-cpp">Foo* f = new(&quot;my foo&quot;) Foo(x,y,z);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2056264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056264</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 29 Apr 2011 19:47:00 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 07:17:36 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Ich würde mich bei so einer Klasse an std::allocator&lt;&gt; orientieren (falls du das noch nicht kennst - das verwenden die STL-Container, um Speicher zu reservieren).</p>
<p>Außerdem kann man benutzerdefinierte operator new() mit beliebigen Parametern definieren, so daß dann sowas möglich ist:</p>
<pre><code class="language-cpp">Foo* f = new(&quot;my foo&quot;) Foo(x,y,z);
</code></pre>
</blockquote>
<p>Hm, ok, das klingt ja schon recht gut.<br />
Darf ich dann in meinem globalen void operator new(size_t size, const char* s); nicht mehr new benutzen, oder? (also das standard new ohne parameter gibts dann nicht mehr?)<br />
Muss ich dann in meinem globalen new malloc() benutzen? Aber dann wird ja nicht der Ctor aufgerufen? Oder ist der new Operator NUR für die Speicherbeschaffung gut und macht der NIE Ctor Aufrufe (es heißt ja immer: Malloc ruft keinen Ctor auf, new schon)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056351</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056351</guid><dc:creator><![CDATA[Alloka]]></dc:creator><pubDate>Sat, 30 Apr 2011 07:17:36 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 07:44:42 GMT]]></title><description><![CDATA[<p><code>operator new()</code> und <code>operator delete()</code> kümmern sich nur um die Speicherverwaltung, Konstruktoren bzw. Destruktoren werden unabhängig davon auf dem Speicherbereich angewendet, den du zurückgegeben hast.<br />
Ob du von deinem eigenen operator new() aus den Default-Operator aufrufen kannst, bin ich mir im Moment nicht sicher, auf jeden Fall solltest du den operator delete auch so schreiben, daß er mit dem von dir präperierten Speicher umgehen kann (und zwar sowohl den &quot;normalen&quot; als auch den Placement-Operator.</p>
<p>PS: Mit welchem Compiler arbeitest du eigentlich? Beim MSVC erinnere ich mich noch an <code>#define new DEBUG_NEW</code> als Diagnosehilfe für Speicherlecks.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056359</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056359</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Sat, 30 Apr 2011 07:44:42 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 09:16:00 GMT]]></title><description><![CDATA[<p>Ich verstehe nicht den Unterschied zwischen placement new und einer globalen überschreibung von operator new.<br />
Wenn ich den operator new so neu definiere:</p>
<pre><code class="language-cpp">void* operator new(size_t size, const char* s);
</code></pre>
<p>dann kann ich ihn doch so aufrufen:</p>
<pre><code class="language-cpp">Foo* f = new (&quot;Hallo&quot;) Foo(2,3, &quot;test&quot;);
</code></pre>
<p>Das ist aber jetzt kein placement new? Auf einer Seite habe ich nämlich gelesen, dass Placement new so aussieht: new (expression) Type(params);<br />
Nach dieser Definition wäre aber mein Aufruf ein placement new. Wann überschreibe ich jetzt placement new und wann einfach nur den globalen new operator?</p>
<p>Noch eine Randfrage: Wenn operator new void* zurückgibt, wieso muss ich dann bei Foo* f = new(&quot;hallo&quot;) Foo; eigentlich nicht downcasten auf Foo*?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056375</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056375</guid><dc:creator><![CDATA[Alloka]]></dc:creator><pubDate>Sat, 30 Apr 2011 09:16:00 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 09:24:16 GMT]]></title><description><![CDATA[<p><code>operator new</code> ist lediglich für die Speicherbeschaffung zuständig, nicht für das Erzeugen des Objekts. <code>new</code> wiederrum beschafft sich intern den Speicher mit <code>operator new</code> und konstruiert dort das Objekt.<br />
Casten musst du also nicht, weil du <code>operator new</code> gar nicht direkt aufrufst. Das geschieht nur intern.</p>
<p>Das placement-new ist ein Spezialfall des überschriebenen <code>operator new</code> . Es ist etwa so definiert:</p>
<pre><code class="language-cpp">void* operator new(size_t, void* ptr) { return ptr; }
</code></pre>
<p>Man kann es also ausnutzen, um in einen schon vorhandenen Speicherplatz ein Objekt zu konstruieren (anders bekommt man den Konstruktor nicht aufgerufen, das kann nur <code>new</code> ).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056376</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Sat, 30 Apr 2011 09:24:16 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 09:33:01 GMT]]></title><description><![CDATA[<p>Alloka schrieb:</p>
<blockquote>
<p>Ich verstehe nicht den Unterschied zwischen placement new und einer globalen überschreibung von operator new.<br />
Wenn ich den operator new so neu definiere:</p>
<pre><code class="language-cpp">void* operator new(size_t size, const char* s);
</code></pre>
<p>dann kann ich ihn doch so aufrufen:</p>
<pre><code class="language-cpp">Foo* f = new (&quot;Hallo&quot;) Foo(2,3, &quot;test&quot;);
</code></pre>
<p>Das ist aber jetzt kein placement new? Auf einer Seite habe ich nämlich gelesen, dass Placement new so aussieht: new (expression) Type(params);<br />
Nach dieser Definition wäre aber mein Aufruf ein placement new.</p>
</blockquote>
<p>Das ist alles eine Frage der Definition - wenn du alle new-Varianten mit Zusatzparametern als Placement new bezeichnest, ist das eins. Wenn du nur die In-Place Konstruktion als Placement new bezeichnest ( <code>Foo* p = malloc(sizeof(p));new(p)Foo(x,yz);</code> ), ist es keins.</p>
<p>Und wie ipsec schon erklärte: operator new arbeitet mit nacktem Speicher - hinter den Kulissen ruft <code>new</code> erst den entsprechenden operator new() auf, erledigt dann den Downcast und ruft den Konstruktor auf. Dieses Verhalten kannst du nicht beeinflussen - du kannst nur festlegen, woher der verwendete Speicher kommt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056380</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Sat, 30 Apr 2011 09:33:01 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 10:57:54 GMT]]></title><description><![CDATA[<p>Ok, langsam lichtet sich der Nebel etwas. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Ich weiß jetzt also, dass es ein keyword new gibt und einen operator new. Operator new kümmert sich nur um die Speicherallokierung. Keyword new ruft operator new auf, danach den Ctor und kümmert sich auch um den Downcast.</p>
<p>Was mir hingegen nicht klar ist:<br />
1. Das hier ist ja placement new:</p>
<pre><code class="language-cpp">void* p = malloc(sizeof(Foo));
Foo* f = new (p) Foo(2);
</code></pre>
<p>Hier erzeugt new also NICHT neuen Speicher sondern legt Foo nur in den vorhandenen Speicher. Kann ich das überhaupt überschreiben? Wie sollte so ein überschriebener globaler placement new überhaupt aussehen?</p>
<p>2. ipsec meinte, placement new ist nur ein Spezialfall eines operator new. Das versteh ich nicht, denn placement new ist ja doch was anderes.<br />
Hier ruft keyword new erst operator new auf und der legt Speicher an. Danach Ctor Aufruf etc.</p>
<pre><code class="language-cpp">Foo* f = new (&quot;Hallo&quot;) Foo(2);
</code></pre>
<p>Das hier sieht ähnlich aus, aber ist was anderes:</p>
<pre><code class="language-cpp">Foo* f = new (p) Foo(2);
</code></pre>
<p>Denn hier ruft keyword new operator new auf aber dieses mal wird operator new KEINEN Speicher allokieren, sondern sofort das Objekt im vorhandenen Speicher initialisieren. Bei einem placement new macht das keyword new also was anderes als bei einem standard operator new. Wie wird das unterschieden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056415</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056415</guid><dc:creator><![CDATA[Alloka]]></dc:creator><pubDate>Sat, 30 Apr 2011 10:57:54 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 11:06:23 GMT]]></title><description><![CDATA[<p>Ich habe dir die Implementierung des Placement-new schon gepostet. Das ist ein überschriebener <code>operator new</code> , der nicht wirklich Speicher allokiert, sondern nur so tut als ob und genau den Pointer als Beginn des Speicherbereichs zurückgibt, der als Parameter übergeben wurde.<br />
<code>new</code> kann nicht wissen, dass eigentlich gar keine Allokation stattfand, sondern konstruiert schön in den von <code>operator new</code> gelieferten Speicherberich das Objekt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056420</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056420</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Sat, 30 Apr 2011 11:06:23 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 11:22:00 GMT]]></title><description><![CDATA[<p>Danke! Du hast übrigens Post ipsec;)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056426</guid><dc:creator><![CDATA[Alloka]]></dc:creator><pubDate>Sat, 30 Apr 2011 11:22:00 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 17:25:53 GMT]]></title><description><![CDATA[<p>new T(Parameter) ruft operator new und placement new auf. new(Speicher) T(Parameter) ist placement new. Du kannst das nicht überschreiben, das wird in &lt;new&gt; definiert. Für deine Allokationsklasse kannst du folgendes machen:</p>
<p>1. Wenn du C++0x hast, geht so etwas:</p>
<pre><code class="language-cpp">namespace memory
{
template&lt;typename T, typename... Args&gt; T *allocate(Args... args)
{
    return new T(args...);
}
}
</code></pre>
<p>2. Wenn nicht, geht je nach Anwendungsfall immer noch ein Define:</p>
<pre><code class="language-cpp">#define NEW_1(Type, ...) CreateObj1(new Type(__VA_ARGS__))
#define NEW_2(call) CreateObj1(new call)

template&lt;typename T&gt; T *CreateObj1(T *ptr)
{
    register_pointer_in_debug_database(ptr);
    return ptr;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2056537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056537</guid><dc:creator><![CDATA[wxSkip]]></dc:creator><pubDate>Sat, 30 Apr 2011 17:25:53 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 18:37:56 GMT]]></title><description><![CDATA[<blockquote>
<p>Darf ich dann in meinem globalen void operator new(size_t size, const char* s); nicht mehr new benutzen, oder? (also das standard new ohne parameter gibts dann nicht mehr?)</p>
</blockquote>
<p>Natürlich gibt's den normalen operator new dann noch, du kannst den Aufruf einfach weiterleiten (ohne den const char* Parameter natürlich, sonst wäre der Aufruf ja rekursiv).</p>
<p>Allerdings halte ich das ganze Vorhaben für Unfug. Aber jeder wie er meinst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056572</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056572</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 30 Apr 2011 18:37:56 GMT</pubDate></item><item><title><![CDATA[Reply to Allokationen zentralisieren on Sat, 30 Apr 2011 22:28:17 GMT]]></title><description><![CDATA[<p>Also wenn ich Probleme mit Speicherlöchern hätte, was ich aber nicht habe, würde ich in allen Dateien, die nicht wie vector.hpp ein berechtigtes Interesse an placement new haben,</p>
<pre><code class="language-cpp">#define new new(__FILE__,__LINE__)
</code></pre>
<p>machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2056650</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2056650</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 30 Apr 2011 22:28:17 GMT</pubDate></item></channel></rss>