title: boost::threads example and heap corruption message
body: <p>I'm quite new to boost::threads, I read the documentation and but i'm having some trouble applying it in practice, perhaps you can help? First of all, I have taken the time to write a self contained code listing that demonstrates 2 types of behavior that I cannot yet understand...</p>
  
  <p>The program allows the user to issue 3 different commands, </p>
  
  <ul>
  <li>task [name]</li>
  <li>info</li>
  <li>quit</li>
  </ul>
  
  <p>The purpose is that <em>task</em> will launch some work on a new thread, but then return back to the command prompt while the work is carried out. The user can give the <em>info</em> command to find out which tasks have completed and which have not.</p>
  
  <p>Im using a dual core Win7 machine and Visual Studio 2008 Express.</p>
  
  <p>Problem 1></p>
  
  <p>Issuing the command, <em>task p1 p2 p3</em>, starts 3 tasks running. This can be checked by issuing <em>info</em>. After a few seconds the work is complete, however for some reason the completed flag is not always set true on 1 or 2 of the tasks.</p>
  
  <p>Problem 2></p>
  
  <p>Quiting the program then produces the following message:</p>
  
  <blockquote>
    <p>Windows has triggered a breakpoint in example.exe. This may be due to a corruption of the heap, which indicates a bug in example.exe or any of the DLLs it has loaded.
    This may also be due to the user pressing F12 while example.exe has focus.
    The output window may have more diagnostic information.</p>
  </blockquote>
  
  <p>Hopefully you can reproduce this behavior and help.</p>
  
  <p>Thanks in advance.
  Alex.</p>
  
  <pre><code>    //WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED
  #include &lt;iostream&gt;  
  #include &lt;string&gt;
  #include &lt;sstream&gt;
  #include &lt;boost/thread.hpp&gt;  
  
  using namespace std;
  
  class task {
  public:
      string mname;
      bool completed;
      void start()
      {
          int a = 0;
          for (int i=0 ; i&lt;10000; i++)
          {
              for (int j=0 ; j&lt;100000; j++)
              {
                  a= i*2;
              }
          }
          this-&gt;completed = true;
      }
      task(string name)
      {
          mname = name;
          completed = false; 
      }
  };
  
  class taskManager{
      public:
          boost::thread_group threads;
          void startTask( string name )
          {
              //add new task to vector list           
              mtasks.push_back( task(name) );
              // execute start() on a new thread
              threads.create_thread( boost::bind( &amp;task::start, &amp;mtasks.back()) );
          }
          int tasksTotal()
          {
              return mtasks.size();
          }
          string taskInfo(int i)
          {
              string compstr("Not Completed");
              if ( mtasks[i].completed == true )
              {
                  compstr = "Completed";
              }
              return mtasks[i].mname + " " + compstr; 
          }
      private:
          vector&lt;task&gt; mtasks; 
  };
  
  int main(int argc, char* argv[])  
  {
      string cmd, temp;
      stringstream os;
      bool quit = false;
      taskManager mm;
  
      cout &lt;&lt; "PROMPT&gt;";
  
      while (quit == false)
      {
          //Wait for a valid command from user
          getline(cin,cmd);
  
          // Reset stringstream and assign new cmd string
          os.clear(); 
          os &lt;&lt; "";
          os &lt;&lt; cmd;
          //parse input string
          while (os &gt;&gt; temp) 
          {               
              if ( temp.compare("task") == 0 )
              {
                  while (os &gt;&gt; temp) { mm.startTask( temp ); }                     
              }
              if ( temp.compare("info") == 0 )
              { 
                  // Returns a list of all completed and not completed tasks
                  for (int i = 0; i&lt;mm.tasksTotal(); i++)
                  {
                      cout &lt;&lt; mm.taskInfo(i).c_str() &lt;&lt; endl;
                  }                           
              }
              if ( temp.compare("quit") == 0 ){ quit = true; }
          }
  
          cout &lt;&lt; "PROMPT&gt;";
      }
  
      mm.threads.join_all();      
  
      return 0;  
  };
  </code></pre>