<?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[Placement new, malloc und Alignment]]></title><description><![CDATA[<p>Hallo,<br />
Ich stehe gerade vor der Frage, ob ein placement new in einem mit malloc (oder einer anderen Allokations-Funktion) reservierten Speicherbereich zu Alignment-Problemen führen kann, vorallem wenn man in den allokierten Speicherbereich unterschiedliche Typen packen will. Relevant ist dabei vor allem etwaiger Overhead, der den ursprünglich allokierten Speicher übersteigt.</p>
<p>Ich habe mal folgendes Beispiel erstellt, bei dem genug Speicher für 5 Objekt des Typs node und 3 Objekt des Typs obj allokiert wird und die Instanzen dann mit placement new in dem Speicherbereich erstellt werden:</p>
<pre><code class="language-cpp">#include &lt;cstdlib&gt;
#include &lt;new&gt;
#include &lt;iostream&gt;

using namespace std;

class node{
public:
  int m_prev;
  int m_next;

  node(int prev, int next): m_prev(prev), m_next(next){

  }
};

class obj{
public:
  int m_x;
  int m_y;
  int m_z;

  obj(int x, int y, int z): m_x(x), m_y(y), m_z(z){

  }
};

int main(int argc, char *argv[]){
  int n = 3;
  int n_nodes = n + 2;

  char *buffer = reinterpret_cast&lt;char*&gt;(
      malloc(sizeof(node) * n_nodes + sizeof(obj) * n));

  node* nodes = reinterpret_cast&lt;node*&gt;(buffer);
  obj* objs = reinterpret_cast&lt;obj*&gt;(nodes + n_nodes);

  node* theNode = nodes;
  obj* theObj = objs;

  for(int i = 0; i &lt; n_nodes; ++i, ++theNode){
    theNode = new(theNode) node(i - 1, i + 1);
  }

  for(int i = 0; i &lt; n; ++i, ++theObj){
    theObj = new(theObj) obj(i, i + 1, i + 2);
  }

  theNode = nodes;
  theObj = objs;

  cout &lt;&lt; &quot;nodes:&quot; &lt;&lt; endl;

  for(int i = 0; i &lt; n_nodes; ++i, ++theNode){
    cout &lt;&lt; theNode-&gt;m_prev &lt;&lt; &quot; &quot; &lt;&lt; theNode-&gt;m_next &lt;&lt; endl;
  } 

  cout &lt;&lt; &quot;objs:&quot; &lt;&lt; endl;

  for(int i = 0; i &lt; n; ++i, ++theObj){
    cout &lt;&lt; theObj-&gt;m_x &lt;&lt; &quot; &quot; &lt;&lt; theObj-&gt;m_y &lt;&lt; &quot; &quot; &lt;&lt; theObj-&gt;m_z &lt;&lt; &quot; &quot; &lt;&lt; endl;
  }

  return 0;
}
</code></pre>
<p>Das ganze funktioniert mit dem GCC problemlos - allerdings soll das ganze portabel und Standard konform sein - was bei solchen Sachen ja nicht immer ganz so einfach ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/238429/placement-new-malloc-und-alignment</link><generator>RSS for Node</generator><lastBuildDate>Wed, 23 Sep 2026 01:03:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/238429.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 10 Apr 2009 12:34:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 12:36:20 GMT]]></title><description><![CDATA[<p>Hallo,<br />
Ich stehe gerade vor der Frage, ob ein placement new in einem mit malloc (oder einer anderen Allokations-Funktion) reservierten Speicherbereich zu Alignment-Problemen führen kann, vorallem wenn man in den allokierten Speicherbereich unterschiedliche Typen packen will. Relevant ist dabei vor allem etwaiger Overhead, der den ursprünglich allokierten Speicher übersteigt.</p>
<p>Ich habe mal folgendes Beispiel erstellt, bei dem genug Speicher für 5 Objekt des Typs node und 3 Objekt des Typs obj allokiert wird und die Instanzen dann mit placement new in dem Speicherbereich erstellt werden:</p>
<pre><code class="language-cpp">#include &lt;cstdlib&gt;
#include &lt;new&gt;
#include &lt;iostream&gt;

using namespace std;

class node{
public:
  int m_prev;
  int m_next;

  node(int prev, int next): m_prev(prev), m_next(next){

  }
};

class obj{
public:
  int m_x;
  int m_y;
  int m_z;

  obj(int x, int y, int z): m_x(x), m_y(y), m_z(z){

  }
};

int main(int argc, char *argv[]){
  int n = 3;
  int n_nodes = n + 2;

  char *buffer = reinterpret_cast&lt;char*&gt;(
      malloc(sizeof(node) * n_nodes + sizeof(obj) * n));

  node* nodes = reinterpret_cast&lt;node*&gt;(buffer);
  obj* objs = reinterpret_cast&lt;obj*&gt;(nodes + n_nodes);

  node* theNode = nodes;
  obj* theObj = objs;

  for(int i = 0; i &lt; n_nodes; ++i, ++theNode){
    theNode = new(theNode) node(i - 1, i + 1);
  }

  for(int i = 0; i &lt; n; ++i, ++theObj){
    theObj = new(theObj) obj(i, i + 1, i + 2);
  }

  theNode = nodes;
  theObj = objs;

  cout &lt;&lt; &quot;nodes:&quot; &lt;&lt; endl;

  for(int i = 0; i &lt; n_nodes; ++i, ++theNode){
    cout &lt;&lt; theNode-&gt;m_prev &lt;&lt; &quot; &quot; &lt;&lt; theNode-&gt;m_next &lt;&lt; endl;
  } 

  cout &lt;&lt; &quot;objs:&quot; &lt;&lt; endl;

  for(int i = 0; i &lt; n; ++i, ++theObj){
    cout &lt;&lt; theObj-&gt;m_x &lt;&lt; &quot; &quot; &lt;&lt; theObj-&gt;m_y &lt;&lt; &quot; &quot; &lt;&lt; theObj-&gt;m_z &lt;&lt; &quot; &quot; &lt;&lt; endl;
  }

  return 0;
}
</code></pre>
<p>Das ganze funktioniert mit dem GCC problemlos - allerdings soll das ganze portabel und Standard konform sein - was bei solchen Sachen ja nicht immer ganz so einfach ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1693935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1693935</guid><dc:creator><![CDATA[maximAL]]></dc:creator><pubDate>Fri, 10 Apr 2009 12:36:20 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 13:06:52 GMT]]></title><description><![CDATA[<p>Ich würde <code>malloc()</code> und <code>new</code> besser nicht mischen. Aber um rohen Speicher anzufordern, kannst du auch <code>operator new</code> verwenden. Das hat die gleiche Schnittstelle wie <code>malloc()</code> : einen <code>size_t</code> -Parameter für die Anzahl zu allokierender Bytes und als Rückgabetyp einen <code>void*</code> auf den angelegten Speicher:</p>
<pre><code class="language-cpp">T* Memory = static_cast&lt;T*&gt;(operator new(sizeof(T) * NumberOfElements));
</code></pre>
<p>Genauso kannst du Speicher freigeben, indem du <code>operator delete</code> benutzt. Aber denk dran, bei Klassentypen vorher den Destruktor explizit aufzurufen, oder gleich <code>delete</code> zu verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1693944</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1693944</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 10 Apr 2009 13:06:52 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 13:34:51 GMT]]></title><description><![CDATA[<p>Das Problem ist allerdings, das man manchmal auf irgendwelche System-spezifischen malloc-Funktionen angewiesen ist <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/1693953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1693953</guid><dc:creator><![CDATA[maximAL]]></dc:creator><pubDate>Fri, 10 Apr 2009 13:34:51 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 15:05:25 GMT]]></title><description><![CDATA[<p>maximAL schrieb:</p>
<blockquote>
<p>Das Problem ist allerdings, das man manchmal auf irgendwelche System-spezifischen malloc-Funktionen angewiesen ist <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>Dann musst du die wrappen und verstecken, am Besten mit RAII, damit korrespondierende malloc() und free() Aufrufe sich nicht mit den new und delete-Aufrufen beißen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1694000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1694000</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 10 Apr 2009 15:05:25 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 15:07:51 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Dann musst du die wrappen und verstecken, am Besten mit RAII, damit korrespondierende malloc() und free() Aufrufe sich nicht mit den new und delete-Aufrufen beißen.</p>
</blockquote>
<p>Ich glaube das Problem liegt eher darin, ob man Placement New auf mit <code>malloc()</code> angeforderten Speicher anwenden dürfe. Der Speicher sollte ja aligned sein, sodass eine Konstruktion möglich ist. Aber wahrscheinlich gibt es wieder irgendwelche Einschränkungen, da bin ich mir gerade überhaupt nicht sicher...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1694004</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1694004</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 10 Apr 2009 15:07:51 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 15:31:10 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Ich glaube das Problem liegt eher darin, ob man Placement New auf mit <code>malloc()</code> angeforderten Speicher anwenden dürfe. Der Speicher sollte ja aligned sein, sodass eine Konstruktion möglich ist. Aber wahrscheinlich gibt es wieder irgendwelche Einschränkungen, da bin ich mir gerade überhaupt nicht sicher...</p>
</blockquote>
<p>malloc ist meines Wissens im Standard nicht erwähnt, außer als Bestandteil der C-Bibliotheken - und die garantieren afaik nicht das C++-Alignment. Ich denke der explizite Aufruf von operator new ist in dem Fall besser als malloc(). Andernfalls müsstest du außerdem später zum korrekten Abräumen der Objekte den Destruktor explizit aufrufen und danach free() - statt wie üblich einfach delete aufzurufen. Gerade für Arrays wäre das dann schon sehr nervig...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1694016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1694016</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 10 Apr 2009 15:31:10 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 16:13:37 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Ich denke der explizite Aufruf von operator new ist in dem Fall besser als malloc().</p>
</blockquote>
<p>Ja, das ist sicherer. Aber maximAL fragte ja wegen unvermeidbarem <code>malloc()</code> . Ich hatte auch mal so ein Problem, als ich eine eigene Speicherverwaltung bastelte, die <code>operator new</code> überladen hat. Da musste ich auf <code>malloc()</code> zurückgreifen, und mir wurde gesagt, das sei okay. <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-229012.html" rel="nofollow">Link</a>...</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Gerade für Arrays wäre das dann schon sehr nervig...</p>
</blockquote>
<p>Oh ja. <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>Wenn es irgendwie anders geht, würde ich sicher nicht so viel Low-Level einsetzen. Eine Möglichkeit stellen auch noch eigene Allokatoren dar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1694046</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1694046</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 10 Apr 2009 16:13:37 GMT</pubDate></item><item><title><![CDATA[Reply to Placement new, malloc und Alignment on Fri, 10 Apr 2009 16:14:21 GMT]]></title><description><![CDATA[<p>Wäre da eventuell <a href="http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html" rel="nofollow">alignment_of</a> von Nutzen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1694048</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1694048</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Fri, 10 Apr 2009 16:14:21 GMT</pubDate></item></channel></rss>