Search code examples
c++multithreadingparameter-passingbeginthread

c++ _beginthread can't pass string as a parameter


I would like to start multiple threads using a sample code like below:

void ThreadFunction(void* param) {
    cout << (string)param << endl;
    _endthread();
    }
int main(int argc, char* argv[]) {
    for (unsigned int i = 1; i <= 10; i++) {
        string String = "This is test nr ";
        String += i;
        _beginthread(ThreadFunction, 0, (void*)&String);
        }
    }

However, I can't get this to work (bad allocation error). What am I doing wrong?


Solution

  • You cannot pass a string as you are doing, but you can pass a string pointer. BUT! You have to be careful that the string stays valid at least until the threads starts... This is usually done by creating the strings on the heap, using new, but it can also work using global objects. Here's how your code could work.

    #include <unistd.h>
    #include <string>
    #include <vector>
    #include <sstream>
    #include <pthread.h>
    
    void ThreadFunction(void* param) 
    {
        std::string* s = reinterpret_cast<std::string*>(param);  
        cout << *s << endl;  
    }                        // <-- no need to call endthread when exiting gracefully
    
    std::vector<std::string> myStrings;
    
    int main(int argc, char* argv[]) 
    {
        // since we will use pointers to strings in the vector myStrings,
        // we need to be sure it is final before using them.
        // you could store some form of smart pointer in the vector to avoid 
        // this issue
        for (unsigned int i = 0; i < 10; i++) 
        {
           std::stringstream ss;
           ss << "This is test nr " << i;
           myStrings.emplace_back(ss.str());
        }
    
        for (unsigned int i = 0; i < myStrings.size(); i++) 
        {
            _beginthread(FunctionName, 0, &myStrings[i]);
        }
    
        // we must pause this thread and wait a little while for the threads
        // to run.  _beginthread does not block, and exiting the program too
        // quickly would prevent our background threads from executing...
    
        sleep(1);
    
        return 0;
    }