Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>n.m. has already given a fine answer, but I found this question interesting so I decided to try to understand it a little better.</p> <p>It turns out then when you call <code>erase()</code> on the first item of an iterator (which we will call <code>item0</code>), here's what the iterator does: it uses the <code>=</code> operator of your class to do <code>item0 = item1</code>. Then it deletes <code>item1</code>.</p> <p>If you don't define your own <code>=</code> operator, I think it will simply copy the memory of your object over from <code>item1</code> to <code>item0</code>, so <code>item0</code> and <code>item1</code> will temporarily be pointing to the same string. Then when <code>item1</code> gets deleted, the string gets freed, leaving <code>item0</code> in an invalid state because it has a pointer to memory that has been freed.</p> <p>Here is some simple test code that reproduces and illuminates the problem:</p> <pre><code>#include &lt;cstring&gt; #include &lt;vector&gt; #include &lt;stdio.h&gt; using namespace std; class Cube { public: char * str; Cube(const Cube &amp;c) { set(c.str); } Cube(const char * s) { set(s); } ~Cube() { clear(); } // is "delete []" necessary? not sure #if 1 // change to 0 to cause a bug void operator=(const Cube &amp;c) { clear(); // necessary to avoid memory leaks printf("operator=\n"); set(c.str); } #endif private: void set(const char * s) { str = new char[strlen(s) + 1]; printf("allocated %p for %s\n", str, s); strcpy(str, s); } void clear() { if (str) { printf("freeing %p: %s\n", str, str); delete str; } } }; int main(int argc, char ** argv) { printf("== CREATING VECTOR ==\n"); vector &lt;Cube&gt; vec; vec.push_back(Cube("octopus")); vec.push_back(Cube("squid")); printf("== BEGINNING ITERATION ==\n"); vector&lt;Cube&gt;::iterator it = vec.begin(); printf("First entry is %p %s\n", it-&gt;str, it-&gt;str); it = vec.erase(it); printf("Second entry is %p %s\n", it-&gt;str, it-&gt;str); // this prints garbage if Cube has no = operator return 0; } </code></pre> <p>This code produces the following output:</p> <pre><code>== CREATING VECTOR == allocated 00350F98 for octopus allocated 00350FB8 for octopus freeing 00350F98: octopus allocated 00350F98 for squid allocated 00350FD8 for squid allocated 00350FE8 for octopus freeing 00350FB8: octopus freeing 00350F98: squid == BEGINNING ITERATION == First entry is 00350FE8 octopus freeing 00350FE8: octopus operator= allocated 00350F98 for squid freeing 00350FD8: squid Second entry is 00350F98 squid freeing 00350F98: squid </code></pre> <p>I compiled and ran this in Windows with MinGW. The command I used was <code>g++ -Wl,--enable-auto-import test.cpp &amp;&amp; a.exe</code>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload