<?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[Eigene Speicherallokation]]></title><description><![CDATA[<p>Hallo zusammen, ich wollte zu Test- und Übungszwecken eine eigene Funktion schreiben, die Speicher allokiert und Objekte initialisiert. Intern greife ich dabei auf <code>malloc()</code> zu, um mir Speicher zu beschaffen.</p>
<p>Konkret auf ein Beispiel angewandt, könnte man es ja so machen ( <code>Logger</code> ist eine Non-POD-Klasse, die ihre Methodenaufrufe dokumentiert):</p>
<pre><code class="language-cpp">Logger* q = static_cast&lt;Logger*&gt;(malloc(sizeof(Logger)));
	q-&gt;Logger::Logger();
</code></pre>
<p>Dazu hätte ich auch gleich eine Frage: Wieso muss man die Klassenzugehörigkeit des Konstruktors explizit angeben? Also weshalb reicht <code>q-&gt;Logger()</code> nicht aus?</p>
<p>Im Weiteren wollte ich das nun als Funktionstemplate realisieren:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
T* Allocate(const T&amp; Object = T())
{
	T* Pointer = static_cast&lt;T*&gt;(malloc(sizeof(T)));
	Pointer-&gt;T::T(Object);

	return Pointer;
}
</code></pre>
<p>Doch merkwürdigerweise erhalte ich beim manuellen Konstruktoraufruf die Fehlermeldung, <code>Logger</code> enthalte kein Element namens <code>T</code> . Aber ich denke, in Templates werden die Vorkommen von <code>T</code> ersetzt?</p>
<p>Abgesehen davon habe ich mir überlegt, dass meine manuelle Speicheranforderung gefährlich sein könnte, wenn Vererbung und Polymorphie im Spiel ist. Aber es geht nur ums Ausprobieren, ich wollte hierbei auch auf <code>new</code> verzichten. Und die zugehörige Freigabefunktion kommt später noch.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/226463/eigene-speicherallokation</link><generator>RSS for Node</generator><lastBuildDate>Wed, 23 Sep 2026 02:04:55 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/226463.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 01 Nov 2008 15:40:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 15:40:59 GMT]]></title><description><![CDATA[<p>Hallo zusammen, ich wollte zu Test- und Übungszwecken eine eigene Funktion schreiben, die Speicher allokiert und Objekte initialisiert. Intern greife ich dabei auf <code>malloc()</code> zu, um mir Speicher zu beschaffen.</p>
<p>Konkret auf ein Beispiel angewandt, könnte man es ja so machen ( <code>Logger</code> ist eine Non-POD-Klasse, die ihre Methodenaufrufe dokumentiert):</p>
<pre><code class="language-cpp">Logger* q = static_cast&lt;Logger*&gt;(malloc(sizeof(Logger)));
	q-&gt;Logger::Logger();
</code></pre>
<p>Dazu hätte ich auch gleich eine Frage: Wieso muss man die Klassenzugehörigkeit des Konstruktors explizit angeben? Also weshalb reicht <code>q-&gt;Logger()</code> nicht aus?</p>
<p>Im Weiteren wollte ich das nun als Funktionstemplate realisieren:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
T* Allocate(const T&amp; Object = T())
{
	T* Pointer = static_cast&lt;T*&gt;(malloc(sizeof(T)));
	Pointer-&gt;T::T(Object);

	return Pointer;
}
</code></pre>
<p>Doch merkwürdigerweise erhalte ich beim manuellen Konstruktoraufruf die Fehlermeldung, <code>Logger</code> enthalte kein Element namens <code>T</code> . Aber ich denke, in Templates werden die Vorkommen von <code>T</code> ersetzt?</p>
<p>Abgesehen davon habe ich mir überlegt, dass meine manuelle Speicheranforderung gefährlich sein könnte, wenn Vererbung und Polymorphie im Spiel ist. Aber es geht nur ums Ausprobieren, ich wollte hierbei auch auf <code>new</code> verzichten. Und die zugehörige Freigabefunktion kommt später noch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608597</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 01 Nov 2008 15:40:59 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 16:10:28 GMT]]></title><description><![CDATA[<p>Die Form <code>Pointer-&gt;T::T(Object);</code> kannte ich bisher noch gar nicht, gibt's nen Grund, dass du kein Placement-new verwendest (was mir eher geeignet scheint)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608615</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608615</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Sat, 01 Nov 2008 16:10:28 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 16:17:07 GMT]]></title><description><![CDATA[<p>Badestrand schrieb:</p>
<blockquote>
<p>Die Form <code>Pointer-&gt;T::T(Object);</code> kannte ich bisher noch gar nicht</p>
</blockquote>
<p>Ich eigentlich auch nicht, ich hab beim Suchen im Internet herausgefunden, dass man das so machen muss.</p>
<p>Badestrand schrieb:</p>
<blockquote>
<p>gibt's nen Grund, dass du kein Placement-new verwendest (was mir eher geeignet scheint)?</p>
</blockquote>
<p>Ja, der new-Operator besitzt zuviele Einschränkungen. Der Rückgabetyp muss <code>void*</code> und der erster Parametertyp <code>size_t</code> sein. Zudem verliert man Typinformationen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608618</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608618</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 01 Nov 2008 16:17:07 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 16:23:26 GMT]]></title><description><![CDATA[<p>Ach so, ich meinte eigentlich statt dem <code>Pointer-&gt;T::T(Object);</code> , also dann</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
T* Allocate(const T&amp; Object = T())
{
    void* memory = malloc( sizeof(T) );
    T* pointer = new (memory) T( Object );
    return pointer;
}
</code></pre>
<p>PS: Placement new macht ja afaik auch nur den Konstruktor-Aufruf, also das was du wolltest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608623</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608623</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Sat, 01 Nov 2008 16:23:26 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 16:36:40 GMT]]></title><description><![CDATA[<p>Okay, das wäre eine Möglichkeit, vielen Dank.</p>
<p>Existiert aber eine Alternative, bei der man ohne <code>new</code> auskommt? Wie gesagt ist das zu Experimentierzwecken und mich hätte es noch gewundert, wie ich manuell ein Objekt an der Stelle im Speicher initialisieren könnte.</p>
<p>Denn auf ein konkretes Beispiel angewandt funktioniert ja der Konstruktoraufruf. Aber wieso ist das im Funktionstemplate nicht möglich (siehe erster Post)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608631</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608631</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 01 Nov 2008 16:36:40 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 17:22:01 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Okay, das wäre eine Möglichkeit, vielen Dank.</p>
<p>Existiert aber eine Alternative, bei der man ohne <code>new</code> auskommt? Wie gesagt ist das zu Experimentierzwecken und mich hätte es noch gewundert, wie ich manuell ein Objekt an der Stelle im Speicher initialisieren könnte.</p>
<p>Denn auf ein konkretes Beispiel angewandt funktioniert ja der Konstruktoraufruf. Aber wieso ist das im Funktionstemplate nicht möglich (siehe erster Post)?</p>
</blockquote>
<p>Eventuell solltest du noch wissen, dass mit <code>new</code> zweierlei Dinge gemeint sein können:</p>
<ol>
<li>die Funktion <code>operator new</code> , die Überladen werden kann</li>
<li>der Operator <code>new</code> , der nicht überladen werden kann.</li>
</ol>
<p>Der Operator <code>new</code> ist der den man in C++ aufruft, wenn man new in einer Anweisung schreibt (allgemein um neuen Speicher zu erhalten, oder für placement new etc.) Die Anweisung <code>T* pt = new T*</code> kann wie folgt aufgefasst werden:<br />
- aufruf von <code>operator new</code> mit sizeof(T) als erstem Argument und allen weiteren argumenten danach (z.B. eine Adresse bei placement new)<br />
- Konstruktion eines T-Objektes im erhaltenen Speicher<br />
- rückgabe des Pointers auf diesen Speicher</p>
<p>Die Konstruktion, explizit einen Konstruktoraufruf zu starten, war mir bisher auch noch nicht untergekommen, vielmehr meine ich irgendwo gelesen zu haben dass das nicht geht, also kein korrektes C++ ist. Zumindest über placement new kommst du also nicht hinweg, allerdings macht das im Grunde nichts anderes als das was du willst: die FUnktion <code>operator new</code> mit pointer-parameter (die bei placement new aufgerufen wird) macht normalerweise nichts anderes als den übergebenen Pointer wieder zurückzugeben, so dass der Operator <code>new</code> nichts weiteres zu tun hat als eben die Konstruktion des Objektes.<br />
(funktioniert übrigens bei new[] genauso)</p>
<p>abgesehn davon sollte dir bewusst sein, dass du den Speicher auch so wieder Freigeben musst wie du ihn besorgt hast, in dem Fall also mit free:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
void Destroy(T* pt)
{
  pt-&gt;~T(); //Manueller Destruktor Aufruf als Pendant zum Placement new
  free(pt);
};
</code></pre>
<p>/edit: informative Lektüre zum Thema ist einerseits das Kapitel über small object allocation im <em>Modern C++ Design</em>, zum anderen könntest du den Standard-Allokatoren deiner STL-Implementation etwas unter die Röcke schauen, wie die das regeln <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608654</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608654</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 01 Nov 2008 17:22:01 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 17:35:58 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Die Konstruktion, explizit einen Konstruktoraufruf zu starten, war mir bisher auch noch nicht untergekommen, vielmehr meine ich irgendwo gelesen zu haben dass das nicht geht, also kein korrektes C++ ist. Zumindest über placement new kommst du also nicht hinweg</p>
</blockquote>
<p>Vielleicht ist es nicht Standard-C++ und eventuell undefiniert. Ich hab auch nicht vor, es weiter zu verwenden, aber ich will es einmal implementiert haben, dann bin ich glücklich. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Und dass es prinzipiell geht, habe ich ja in meinem ersten Post gezeigt:</p>
<pre><code class="language-cpp">Logger* q = static_cast&lt;Logger*&gt;(malloc(sizeof(Logger)));
	q-&gt;Logger::Logger();
</code></pre>
<p>Aber ich kann mir nicht erklären, dass die Template-Version davon nicht funktioniert, weil der Typ <code>T</code> anscheinend nicht ersetzt wird und ich deshalb eine Fehlermeldung ( <code>Logger</code> besitze kein Element <code>T</code> ) erhalte. Kann mir jemand erklären, wieso das nicht funktioniert?</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
T* Allocate(const T&amp; Object = T())
{
	T* Pointer = static_cast&lt;T*&gt;(malloc(sizeof(T)));
	Pointer-&gt;T::T(Object);

	return Pointer;
}
</code></pre>
<p>Es sollte aber schon irgendwie gehen. Im Notfall bin ich stur und mach es mit Makros... :p</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>abgesehn davon sollte dir bewusst sein, dass du den Speicher auch so wieder Freigeben musst wie du ihn besorgt hast, in dem Fall also mit free:</p>
</blockquote>
<p>Ja, genau so eine Funktion hab ich inzwischen auch schon geschrieben. Und zu Beginn sagte ich ja, diese würde noch implementiert werden. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608667</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 01 Nov 2008 17:35:58 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 18:45:30 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Aber ich kann mir nicht erklären, dass die Template-Version davon nicht funktioniert, weil der Typ <code>T</code> anscheinend nicht ersetzt wird und ich deshalb eine Fehlermeldung ( <code>Logger</code> besitze kein Element <code>T</code> ) erhalte. Kann mir jemand erklären, wieso das nicht funktioniert?</p>
</blockquote>
<p>Das liegt vermutlich daran, dass bei Templates nur die Typbezeichner ersetzt werden. Konstruktoren sind hingegen Methoden, die allerdings den gleichen Namen haben. Aus pointer-&gt;T::T() macht der Compiler also durch die Ersetzung des Typs ein pointer-&gt;Logger::T().<br />
Um das wirklich umzusetzen müsstest du also wirklich zu Makros greifen.</p>
<p>Oder du sagst dir, dass es genug ist, es versucht zu haben und dabei festgestellt zu haben dass das kein Standard-C++ ist und nur mit Makros. Ich würd mir nicht anmaßen sowas hinzuferkeln, man hat ja schließlich doch noch ein bisschen Selbstachtung und Anstand <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608701</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608701</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 01 Nov 2008 18:45:30 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sat, 01 Nov 2008 19:10:25 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Oder du sagst dir, dass es genug ist, es versucht zu haben und dabei festgestellt zu haben dass das kein Standard-C++ ist und nur mit Makros. Ich würd mir nicht anmaßen sowas hinzuferkeln, man hat ja schließlich doch noch ein bisschen Selbstachtung und Anstand <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Makros sind aber krass. <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="😃"
    /><br />
Nun gut, dann mach ichs wenigstens noch mit Placement New. Und die Makro-Lösung muss ich auch probieren, hehe.</p>
<p>Aber das mit den Templates versteh ich trotzdem nicht ganz. Bei STL-Containern werden auch Funktionen übergeben, die dann entsprechend eingesetzt werden. Und Folgendes geht ja auch:</p>
<pre><code class="language-cpp">Pointer-&gt;~T();
</code></pre>
<p>Wieso wird das hingenommen, der Aufruf eines Konstruktors jedoch nicht? Niemand ist ja so beschränkt, als Templateargument einen Bezeichner zu wählen, der sich mit den Methoden der Klasse überschneidet. Welchen Sinn hat es also, <code>T()</code> als Methodenaufruf nicht zu ersetzen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Und ist Placement New in jedem Falle definiertes Verhalten (vorausgesetzt, es wurde genügend Speicherplatz allokiert)? Werden automatisch die richtigen Konstruktoren aufgerufen, auch bei Vererbung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608711</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 01 Nov 2008 19:10:25 GMT</pubDate></item><item><title><![CDATA[Reply to Eigene Speicherallokation on Sun, 02 Nov 2008 09:58:36 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Und ist Placement New in jedem Falle definiertes Verhalten (vorausgesetzt, es wurde genügend Speicherplatz allokiert)?</p>
</blockquote>
<p>Solang du incht in irgendwelche Alignmentprobleme läufst ja.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Werden automatisch die richtigen Konstruktoren aufgerufen, auch bei Vererbung?</p>
</blockquote>
<p>Es wird der Konstruktor des Typs aufgerufen, für den du das new aufrufst. Und der ruft natürlich die Konstruktoren aller geerbten Klassen auf, wie gewöhnlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1608848</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1608848</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sun, 02 Nov 2008 09:58:36 GMT</pubDate></item></channel></rss>