Shahzad
Shahzad

Reputation: 315

passing structure object as parameter to a thread

This code runs successfully and MQStruct constructor initialized the values as well, I can see in ExecuteThread function but in TestFunction, I get the garbage values for MQStruct.

I am passing address of struct "&MQStructObj" to _beginthreadex for parameters and This is the problem I guess

struct MQStruct {
    MQStruct()
    {
        pointer=NULL;
        serviceName=NULL;
        durability=0;
        msgType=0;
        msgHeader=0;
        msgId=NULL;
        payload=NULL;
        payloadSize=0;
        ttl=0;
        priority=0;
    }

    void* pointer;
    wchar_t *serviceName; 
    int durability; 
    int msgType; 
    int msgHeader; 
    wchar_t *msgId; 
    wchar_t *payload; 
    int payloadSize; 
    int ttl; 
    int priority;
};


int ExecuteThread() {

    HANDLE   heartBeatThread;
    unsigned int hbThreadID;
    int result = 0;

        MQStruct MQStructObj;
        MQStructObj.pointer=this;

    heartBeatThread = (HANDLE)_beginthreadex(NULL, 0 , &TestFunction, &MQStructObj, 0/*CREATE_SUSPENDED*/, &hbThreadID);


    if ( heartBeatThread == 0 )
    {
        result = -1;
        LogEvent(DEBUG_LOG,0, "Fail to create thread");
    }


    CloseHandle(heartBeatThread);

    return result;
}

Upvotes: 1

Views: 1559

Answers (2)

simonc
simonc

Reputation: 42185

MQStructObj is declared on the stack so will go out of scope and potentially be overwritten as soon as ExecuteThread completes.

If you want to use a stack object here, you'll need to add some synchronisation to allow your new thread to copy from MQStructObj before ExecuteThread returns.

Alternatively, normally preferably, you could allocate MQStructObj dynamically and leave the new thread to clean it up at its leisure

MQStruct* MQStructObj = new MQStruct();
MQStructObj->pointer=this;
heartBeatThread = (HANDLE)_beginthreadex(NULL, 0 , &TestFunction, MQStructObj, 0, &hbThreadID);
if ( heartBeatThread == 0 ) { // error
    delete MQStructObj;
    result = -1;
}
// ownership of MQStructObj transferred to new thread

Upvotes: 2

WhozCraig
WhozCraig

Reputation: 66234

You guessed correctly.

You're passing the address of a local variable to your thread-proc-startup, then leaving scope (and destroying the object in the process). References to this object in your thread proc are there-after undefined behavior.

Dynamically allocate one with new and let the thread proc delete it.

Upvotes: 2

Related Questions