Boost :: threads example and heap error message

I am completely new to increase :: threads, I read the documentation, but I have some problems with putting it into practice, maybe you can help? First of all, I took the time to write a personal code list that demonstrates two types of behavior that I still cannot understand ...

The program allows the user to issue 3 different commands,

  • Task [name]
  • Information
  • go out

The goal is that the task will start some work on the new thread, but then return to the command line while the work is in progress. The user can give the info command to find out which tasks were completed and which were not.

Im using a dual-core Win7 machine and Visual Studio 2008 Express.

Problem 1>

Issuing a command, task p1 p2 p3, starts 3 tasks to be performed. This can be verified by sending information. After a few seconds, the work is completed, however, for some reason, the completed flag is not always set for 1 or 2 tasks.

Problem 2>

When you exit the program, the following message is displayed:

Windows called a breakpoint in the example.exe file. This may be due to heap corruption, which indicates an error in example.exe or any of the loaded dll files. It can also be caused by pressing the F12 button when example.exe has focus. The output window may contain more diagnostic information.

We hope you can reproduce this behavior and help.

Thanks in advance. Alex

//WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED #include <iostream> #include <string> #include <sstream> #include <boost/thread.hpp> using namespace std; class task { public: string mname; bool completed; void start() { int a = 0; for (int i=0 ; i<10000; i++) { for (int j=0 ; j<100000; j++) { a= i*2; } } this->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( &task::start, &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<task> mtasks; }; int main(int argc, char* argv[]) { string cmd, temp; stringstream os; bool quit = false; taskManager mm; cout << "PROMPT>"; while (quit == false) { //Wait for a valid command from user getline(cin,cmd); // Reset stringstream and assign new cmd string os.clear(); os << ""; os << cmd; //parse input string while (os >> temp) { if ( temp.compare("task") == 0 ) { while (os >> temp) { mm.startTask( temp ); } } if ( temp.compare("info") == 0 ) { // Returns a list of all completed and not completed tasks for (int i = 0; i<mm.tasksTotal(); i++) { cout << mm.taskInfo(i).c_str() << endl; } } if ( temp.compare("quit") == 0 ){ quit = true; } } cout << "PROMPT>"; } mm.threads.join_all(); return 0; }; 
+7
source share
1 answer

The problem with your code in the taskManager::startTask :

 mtasks.push_back( task(name) ); // execute start() on a new thread threads.create_thread( boost::bind( &task::start, &mtasks.back()) 

The problem is that when you drop a new task, your vector may need to redistribute some space and thus invalidate links to your old vector elements, so the following taskinfo calls will refer to the wrong elements. When you delete old items, your heap will be somehow damaged.

An easy fix is ​​to reserve some space for the vector in the constructor of your taskManager class, however you should probably redesign your task / taskmanager model. Another way is to use std::deque as it will not reallocate memory.

+4
source

All Articles