<?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[[Erledigt] list::const_iterator crasht beim Vergleich]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich iteriere (in einer Methode einer Klasse) durch eine (Member-)Liste ('std::list') und führe dabei einen Vergleich von Iteratoren aus. Das klappt auch recht gut.</p>
<p>Nun brauche ich von der besagten Methode aber auch eine const-Version. Um nicht alles neuschreiben zu müssen, const-caste ich einfach 'this' und rufe die non-const-Version auf. Das ist sicher, da keine Schreiboperationen ausgeführt werden. Dachte ich. Leider crasht der Code bei dem Vergleich zweier Iteratoren; der Debugger sagt mit, die beiden Iteratoren seien inkompatibel. Und in der Tat scheinen die Iteratoren zu unterschiedlichen 'std::list'-Instanzen zu gehören (sie besitzen beide einen Zeiger auf ihren Container, der unterschiedlich ist).</p>
<p>Woran kann das liegen? Ich bin sicher, dass der Container *kein* anderer ist.</p>
<p>Hier mal der Code, wobei ich befürchte, dass er nicht viel bringt:</p>
<pre><code class="language-cpp">typename list_type::iterator skip_list_find(key_type const&amp; key) {
    // 'm_nodes' ist definiert als list_type.
    typename list_type::iterator p = m_nodes.begin();

    if (empty())
        return p;

    int y = m_height;

    while (y &gt; 0) {
        --y;
        while (
            // In der nächsten Zeile erfolgt der Crash:
            p-&gt;next[y] != m_nodes.end() and
            not m_comp(key, p-&gt;next[y]-&gt;value.first)
        )
            p = p-&gt;next[y];
    }

    return p;
}

typename list_type::const_iterator skip_list_find(key_type const&amp; key) const {
    // This is well-defined because we will not use write access at any time.
    skip_list* mutable_this = const_cast&lt;skip_list*&gt;(this);
    return static_cast&lt;list_type::const_iterator&gt;(mutable_this-&gt;skip_list_find(key));
}
</code></pre>
<p>Die Definition von 'list_type' sieht folgendermaßen aus:</p>
<pre><code class="language-cpp">struct node;

typedef std::list&lt;
    node, typename allocator_type::rebind&lt;node&gt;::other
&gt; list_type;

struct node {
    value_type value;
    std::vector&lt;typename list_type::iterator&gt; next;
};
</code></pre>
<p>Ach ja, ich habe jetzt die Const-Version doch mal neugeschrieben (einfach den Code kopiert und 'iterator' durch 'const_iterator' ersetzt. Ändert nichts: gleicher Fehler).</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/202446/erledigt-list-const_iterator-crasht-beim-vergleich</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 17:13:29 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/202446.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 11 Jan 2008 16:19:46 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Erledigt] list::const_iterator crasht beim Vergleich on Fri, 11 Jan 2008 17:01:34 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich iteriere (in einer Methode einer Klasse) durch eine (Member-)Liste ('std::list') und führe dabei einen Vergleich von Iteratoren aus. Das klappt auch recht gut.</p>
<p>Nun brauche ich von der besagten Methode aber auch eine const-Version. Um nicht alles neuschreiben zu müssen, const-caste ich einfach 'this' und rufe die non-const-Version auf. Das ist sicher, da keine Schreiboperationen ausgeführt werden. Dachte ich. Leider crasht der Code bei dem Vergleich zweier Iteratoren; der Debugger sagt mit, die beiden Iteratoren seien inkompatibel. Und in der Tat scheinen die Iteratoren zu unterschiedlichen 'std::list'-Instanzen zu gehören (sie besitzen beide einen Zeiger auf ihren Container, der unterschiedlich ist).</p>
<p>Woran kann das liegen? Ich bin sicher, dass der Container *kein* anderer ist.</p>
<p>Hier mal der Code, wobei ich befürchte, dass er nicht viel bringt:</p>
<pre><code class="language-cpp">typename list_type::iterator skip_list_find(key_type const&amp; key) {
    // 'm_nodes' ist definiert als list_type.
    typename list_type::iterator p = m_nodes.begin();

    if (empty())
        return p;

    int y = m_height;

    while (y &gt; 0) {
        --y;
        while (
            // In der nächsten Zeile erfolgt der Crash:
            p-&gt;next[y] != m_nodes.end() and
            not m_comp(key, p-&gt;next[y]-&gt;value.first)
        )
            p = p-&gt;next[y];
    }

    return p;
}

typename list_type::const_iterator skip_list_find(key_type const&amp; key) const {
    // This is well-defined because we will not use write access at any time.
    skip_list* mutable_this = const_cast&lt;skip_list*&gt;(this);
    return static_cast&lt;list_type::const_iterator&gt;(mutable_this-&gt;skip_list_find(key));
}
</code></pre>
<p>Die Definition von 'list_type' sieht folgendermaßen aus:</p>
<pre><code class="language-cpp">struct node;

typedef std::list&lt;
    node, typename allocator_type::rebind&lt;node&gt;::other
&gt; list_type;

struct node {
    value_type value;
    std::vector&lt;typename list_type::iterator&gt; next;
};
</code></pre>
<p>Ach ja, ich habe jetzt die Const-Version doch mal neugeschrieben (einfach den Code kopiert und 'iterator' durch 'const_iterator' ersetzt. Ändert nichts: gleicher Fehler).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1434985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1434985</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Fri, 11 Jan 2008 17:01:34 GMT</pubDate></item><item><title><![CDATA[Reply to [Erledigt] list::const_iterator crasht beim Vergleich on Fri, 11 Jan 2008 16:46:47 GMT]]></title><description><![CDATA[<p>Kann an dem Code nichts finden, allerdings machst du ja ein paar Annahmen über den Inhalt, die verletzt sein könnten. Ein paar zusätzliche asserts wären möglicherweise hilfreich.<br />
Ganz nebenbei:</p>
<pre><code class="language-cpp">typedef std::list&lt;
    node, typename allocator_type::template rebind&lt;node&gt;::other
&gt; list_type;
</code></pre>
<p>wenn, wie ich annehme, allocator_type von einem Templateargument abhängt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1434997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1434997</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 11 Jan 2008 16:46:47 GMT</pubDate></item><item><title><![CDATA[Reply to [Erledigt] list::const_iterator crasht beim Vergleich on Fri, 11 Jan 2008 16:51:59 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Kann an dem Code nichts finden, allerdings machst du ja ein paar Annahmen über den Inhalt, die verletzt sein könnten. Ein paar zusätzliche asserts wären möglicherweise hilfreich.</p>
</blockquote>
<p>Hmm, werde mal schauen. Allerdings sind die Annahmen über den Inhalt doch sehr begrenzt. Die einzige (theoretisch) verletzbare Annahme, die ich im Moment sehe, ist der Array-Index von 'next' und past-the-end 'p'.</p>
<blockquote>
<p>Ganz nebenbei:</p>
<pre><code class="language-cpp">typedef std::list&lt;
    node, typename allocator_type::template rebind&lt;node&gt;::other
&gt; list_type;
</code></pre>
<p>wenn, wie ich annehme, allocator_type von einem Templateargument abhängt.</p>
</blockquote>
<p>Ja, dachte ich mir schon. So hatte ich's ursprünglich auch, da der VC++ es aber auch ohne akzeptiert hat, habe ich's wieder rausgelassen. Tests mit dem GCC und Comeau (soweit möglich) folgen eh noch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1434999</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1434999</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Fri, 11 Jan 2008 16:51:59 GMT</pubDate></item><item><title><![CDATA[Reply to [Erledigt] list::const_iterator crasht beim Vergleich on Fri, 11 Jan 2008 17:01:16 GMT]]></title><description><![CDATA[<p>Okay, ich habe den Fehler gefunden.</p>
<p>Die konstante Instanz der Klasse, für welche diese Methode aufgerufen wird, ist die Kopie einer nicht-konstanten Instanz. Im Kopierkonstruktor wird selbstverständlich die 'm_nodes'-Liste kopiert. Die 'next'-Zeiger seiner Elemente hingegen habe ich nicht angepasst.</p>
<p>Ba, widerlich. Jetzt muss ich das auch noch manuell implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1435002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1435002</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Fri, 11 Jan 2008 17:01:16 GMT</pubDate></item></channel></rss>