<?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[Laufzeitverhalten delete[]]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich versuche gerade, eine Matrix-Klasse zu implementieren, und bin dabei auf ein relativ interessantes Laufzeitverhalten von delete[] gestoßen.</p>
<p>Zum Testen habe ich mir ein Array von Matrix-Pointern angelegt, das ich mit Matrizen zufälliger Größe befülle, eine paar Zugriffe mache, und dann wieder lösche.</p>
<p>Zufällig habe ich dann entdeckt, dass die Löschung des Arrays bei einer Größe von 464284 bis 517149 Elementen wesentlich länger dauert, als normal (über 95ms; &lt;464284 benötigt bis ca. 40ms, &gt;517149 benötigt ab ca. 45ms; reproduzierbar, da ich rand() immer gleich initialisiere). Möglicherweise trifft das auch noch auf weitere Bereiche zu, aber ich habe ja nicht wirklich eine Möglichkeit, das erschöpfend zu testen. <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>
<p>Ich habe dann durch valgrind festgestellt, dass, wenn es länger dauert, bei den Aufrufen der Operatoren dann statt</p>
<pre><code>operator delete -&gt; free -&gt; 0x752B0
</code></pre>
<p>scheinbar einmal</p>
<pre><code>operator delete -&gt; free -&gt; 0x752B0 -&gt; 0x739D0
</code></pre>
<p>aufgerufen wird, wobei in der Funktion dann einmalig die ganze Zeit verbraten wird.</p>
<p>Leider ist es mir nicht gelungen, aus den Funktionspointern auf die entsprechenden C-Library-Funktionen zurückzuschließen, weshalb ich nicht nachvollziehen kann, was da genau passiert.<br />
0x739D0 wird aber scheinbar indirekt von malloc (23 mal) und free (1 mal) aufgerufen.</p>
<p>Kann mir jemand erklären, was da passiert?</p>
<p>Mit freundlichen Grüßen</p>
<p>Christian</p>
<p>Die relevanten Teile der Matrix-Klasse:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class Matrix
{
public:
  Matrix(const int&amp; numberOfRows, const int&amp; numberOfColums,
         const T&amp; defaultValue);

  const int &amp;NumberOfRows() const;
  const int &amp;NumberOfColumns() const;

  ~Matrix();

private:
  int numberOfRows_;
  int numberOfColumns_;

  T* elements_;
};

template &lt;typename T&gt;
Matrix&lt;T&gt;::Matrix(const int&amp; numberOfRows, const int&amp; numberOfColumns,
                  const T&amp; defaultValue)
  : numberOfRows_   (numberOfRows),
    numberOfColumns_(numberOfColumns),
    elements_       (new T[numberOfRows * numberOfColumns])
{
   if (numberOfRows &lt; 1 || numberOfColumns &lt; 1)
   {
     throw();
   }

  for (int counter = 0; counter &lt; numberOfRows * numberOfColumns; ++counter)
  {
    elements_[counter] = defaultValue;
  }
}

template &lt;typename T&gt;
inline const int&amp; Matrix&lt;T&gt;::NumberOfRows() const
{
  return numberOfRows_;
}

template &lt;typename T&gt;
inline const int&amp; Matrix&lt;T&gt;::NumberOfColumns() const
{
  return numberOfColumns_;
}

template &lt;typename T&gt;
Matrix&lt;T&gt;::~Matrix()
{
  delete[] elements_;
}
</code></pre>
<p>Mein Testaufbau (ohne Zeitmessung) sieht ungefähr folgendermaßen aus:</p>
<pre><code class="language-cpp">const int numberOfTrials     = 464284;
  const int maxNumberOfRows    = 10;
  const int maxNumberOfColumns = 10;

  srand(123456);

  Matrix&lt;double&gt;** pointer = new Matrix&lt;double&gt;*[numberOfTrials];

  int numberOfRows    = 0;
  int numberOfColumns = 0;
  for (int counter = 0; counter &lt; numberOfTrials; ++counter)
  {
    numberOfRows = 1 + int(double(rand()) / double(RAND_MAX) * double(maxNumberOfRows - 1));
    numberOfColumns = 1 + int(double(rand()) / double(RAND_MAX) * double(maxNumberOfColumns - 1));

    pointer[counter] = new Matrix&lt;double&gt;(numberOfRows, numberOfColumns, 0.0);
  }

  //andere Tests, Zugriffe, etc.

//Dieser Teil braucht jetzt unterschiedlich lange

  for (int counter = 0; counter &lt; numberOfTrials; ++counter)
  {
    delete pointer[counter];
  }

  delete[] pointer;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/279937/laufzeitverhalten-delete</link><generator>RSS for Node</generator><lastBuildDate>Mon, 24 Aug 2026 08:05:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/279937.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 06 Jan 2011 14:34:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 14:34:34 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich versuche gerade, eine Matrix-Klasse zu implementieren, und bin dabei auf ein relativ interessantes Laufzeitverhalten von delete[] gestoßen.</p>
<p>Zum Testen habe ich mir ein Array von Matrix-Pointern angelegt, das ich mit Matrizen zufälliger Größe befülle, eine paar Zugriffe mache, und dann wieder lösche.</p>
<p>Zufällig habe ich dann entdeckt, dass die Löschung des Arrays bei einer Größe von 464284 bis 517149 Elementen wesentlich länger dauert, als normal (über 95ms; &lt;464284 benötigt bis ca. 40ms, &gt;517149 benötigt ab ca. 45ms; reproduzierbar, da ich rand() immer gleich initialisiere). Möglicherweise trifft das auch noch auf weitere Bereiche zu, aber ich habe ja nicht wirklich eine Möglichkeit, das erschöpfend zu testen. <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>
<p>Ich habe dann durch valgrind festgestellt, dass, wenn es länger dauert, bei den Aufrufen der Operatoren dann statt</p>
<pre><code>operator delete -&gt; free -&gt; 0x752B0
</code></pre>
<p>scheinbar einmal</p>
<pre><code>operator delete -&gt; free -&gt; 0x752B0 -&gt; 0x739D0
</code></pre>
<p>aufgerufen wird, wobei in der Funktion dann einmalig die ganze Zeit verbraten wird.</p>
<p>Leider ist es mir nicht gelungen, aus den Funktionspointern auf die entsprechenden C-Library-Funktionen zurückzuschließen, weshalb ich nicht nachvollziehen kann, was da genau passiert.<br />
0x739D0 wird aber scheinbar indirekt von malloc (23 mal) und free (1 mal) aufgerufen.</p>
<p>Kann mir jemand erklären, was da passiert?</p>
<p>Mit freundlichen Grüßen</p>
<p>Christian</p>
<p>Die relevanten Teile der Matrix-Klasse:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class Matrix
{
public:
  Matrix(const int&amp; numberOfRows, const int&amp; numberOfColums,
         const T&amp; defaultValue);

  const int &amp;NumberOfRows() const;
  const int &amp;NumberOfColumns() const;

  ~Matrix();

private:
  int numberOfRows_;
  int numberOfColumns_;

  T* elements_;
};

template &lt;typename T&gt;
Matrix&lt;T&gt;::Matrix(const int&amp; numberOfRows, const int&amp; numberOfColumns,
                  const T&amp; defaultValue)
  : numberOfRows_   (numberOfRows),
    numberOfColumns_(numberOfColumns),
    elements_       (new T[numberOfRows * numberOfColumns])
{
   if (numberOfRows &lt; 1 || numberOfColumns &lt; 1)
   {
     throw();
   }

  for (int counter = 0; counter &lt; numberOfRows * numberOfColumns; ++counter)
  {
    elements_[counter] = defaultValue;
  }
}

template &lt;typename T&gt;
inline const int&amp; Matrix&lt;T&gt;::NumberOfRows() const
{
  return numberOfRows_;
}

template &lt;typename T&gt;
inline const int&amp; Matrix&lt;T&gt;::NumberOfColumns() const
{
  return numberOfColumns_;
}

template &lt;typename T&gt;
Matrix&lt;T&gt;::~Matrix()
{
  delete[] elements_;
}
</code></pre>
<p>Mein Testaufbau (ohne Zeitmessung) sieht ungefähr folgendermaßen aus:</p>
<pre><code class="language-cpp">const int numberOfTrials     = 464284;
  const int maxNumberOfRows    = 10;
  const int maxNumberOfColumns = 10;

  srand(123456);

  Matrix&lt;double&gt;** pointer = new Matrix&lt;double&gt;*[numberOfTrials];

  int numberOfRows    = 0;
  int numberOfColumns = 0;
  for (int counter = 0; counter &lt; numberOfTrials; ++counter)
  {
    numberOfRows = 1 + int(double(rand()) / double(RAND_MAX) * double(maxNumberOfRows - 1));
    numberOfColumns = 1 + int(double(rand()) / double(RAND_MAX) * double(maxNumberOfColumns - 1));

    pointer[counter] = new Matrix&lt;double&gt;(numberOfRows, numberOfColumns, 0.0);
  }

  //andere Tests, Zugriffe, etc.

//Dieser Teil braucht jetzt unterschiedlich lange

  for (int counter = 0; counter &lt; numberOfTrials; ++counter)
  {
    delete pointer[counter];
  }

  delete[] pointer;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2003191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003191</guid><dc:creator><![CDATA[739D0]]></dc:creator><pubDate>Thu, 06 Jan 2011 14:34:34 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 14:38:55 GMT]]></title><description><![CDATA[<p>1. Warum baust du std::vector schlecht nach, anstatt std::vector zu benutzen?<br />
2. Hast du auch alle Optimierungen eingeschaltet? Deinen Testaufbau würde mein Compiler nämlich gänzlich wegoptimieren. Wenn du also eine von Null verschiedene Laufzeit herausbekommst, optimiert dein Compiler wohl nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003196</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003196</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 06 Jan 2011 14:38:55 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 14:48:04 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>1. Warum baust du std::vector schlecht nach, anstatt std::vector zu benutzen?</p>
</blockquote>
<p>Naja, ich bin noch Anfänger. <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>
<p>SeppJ schrieb:</p>
<blockquote>
<p>2. Hast du auch alle Optimierungen eingeschaltet? Deinen Testaufbau würde mein Compiler nämlich gänzlich wegoptimieren. Wenn du also eine von Null verschiedene Laufzeit herausbekommst, optimiert dein Compiler wohl nicht.</p>
</blockquote>
<p>Grade -02 drangehängt, und es wird dadurch nur generell um ein paar Millisekunden schneller. Ich schreibe in die Matrizen beim Testen Werte rein; der Teil fehlt lediglich im geposteten Code.</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003201</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003201</guid><dc:creator><![CDATA[739D0]]></dc:creator><pubDate>Thu, 06 Jan 2011 14:48:04 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 15:21:25 GMT]]></title><description><![CDATA[<p>739D0 schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>1. Warum baust du std::vector schlecht nach, anstatt std::vector zu benutzen?</p>
</blockquote>
<p>Naja, ich bin noch Anfänger. <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>Schlechte Ausrede. Von deinem Codestil her zu urteilen, bist du weit fortgeschrittener als jemand der die STL nicht kennt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003213</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003213</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 06 Jan 2011 15:21:25 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 15:27:09 GMT]]></title><description><![CDATA[<p>Gut, ich habe den Test schnell zusammengehackt, wobei ich dann meistens vergesse, dass es die STL überhaupt gibt. <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="🙂"
    /><br />
Leider bringt es auch nichts, wenn ich std::vector statt meinem ** verwende. Der Bereich, in dem das Phänomen auftritt, verschiebt sich dann etwas, aber es ist immer noch vorhanden. Bis 500000 Elemente scheint alles zu passen, dann dauert's auf einmal länger, und ab 750000 geht's wieder gewohnt schnell.<br />
Ja, ich weiß, mit so vielen Matrizen wird man selten hantieren, vor allem nicht in der Form, aber das Problem bei der Sache ist eigentlich nur, dass da etwas passiert, dass ich nicht wirklich nachvollziehen kann, und daher mache ich mir Gedanken, ob ich nicht etwas übersehen habe.</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003216</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003216</guid><dc:creator><![CDATA[739D0]]></dc:creator><pubDate>Thu, 06 Jan 2011 15:27:09 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Thu, 06 Jan 2011 17:52:26 GMT]]></title><description><![CDATA[<p>Also wenn du k Matrizen jeweils zufälliger Größe löschst, tritt dabei genau einmal diese &quot;Anomalie&quot; auf, richtig verstanden? (464284&lt;k&lt;517149)<br />
Welche Größe hat die Matrix, deren Freigabe außergewöhnlich lange dauert?<br />
Lässt sich das auch mit Matrizen konstanter Größe reproduzieren? Mit primitiven Datentypen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003297</guid><dc:creator><![CDATA[wx++]]></dc:creator><pubDate>Thu, 06 Jan 2011 17:52:26 GMT</pubDate></item><item><title><![CDATA[Reply to Laufzeitverhalten delete[] on Fri, 07 Jan 2011 10:22:54 GMT]]></title><description><![CDATA[<p>wx++ schrieb:</p>
<blockquote>
<p>Also wenn du k Matrizen jeweils zufälliger Größe löschst, tritt dabei genau einmal diese &quot;Anomalie&quot; auf, richtig verstanden? (464284&lt;k&lt;517149)</p>
</blockquote>
<p>Ja, das ist genau das, was ich beobachte.</p>
<p>wx++ schrieb:</p>
<blockquote>
<p>Welche Größe hat die Matrix, deren Freigabe außergewöhnlich lange dauert?<br />
Lässt sich das auch mit Matrizen konstanter Größe reproduzieren? Mit primitiven Datentypen?</p>
</blockquote>
<p>Mit primitiven Datentypen ist es mir jetzt nicht gelungen, das zu reproduzieren, aber das kann auch an der Schrittgröße liegen, mit der ich die Anzahl der Element erhöht habe.<br />
Für Matrizen mit konstanter Größe ist der Bereich etwas anders, aber es tritt ebenfalls auf. Die Matrix, die das Verhalten auslöst, unterscheidet sich also nicht von den anderen.<br />
Anscheinend ist es immer die letzte Matrix im Array.<br />
Allerdings tritt es nicht auf, wenn ich beim Freigeben von hinten nach vorne laufe...</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003497</guid><dc:creator><![CDATA[739D0]]></dc:creator><pubDate>Fri, 07 Jan 2011 10:22:54 GMT</pubDate></item></channel></rss>