1

このコードは正常に実行され、MQStruct コンストラクターも値を初期化しました。ExecuteThread 関数で確認できますが、TestFunction では、MQStruct のガベージ値を取得します。

構造体 "&MQStructObj" のアドレスをパラメーターの _beginthreadex に渡していますが、これは私が推測する問題です

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;
}
4

2 に答える 2

2

あなたは正しく推測しました。

ローカル変数のアドレスを thread-proc-startup に渡し、スコープを離れます (そしてプロセス内のオブジェクトを破棄します)。スレッド プロシージャでのこのオブジェクトへの参照は、その後未定義の動作になります。

で動的に割り当てnew、スレッドdeleteにそれを処理させます。

于 2013-01-15T13:11:49.933 に答える
2

MQStructObjスタックで宣言されているため、スコープ外になり、ExecuteThread完了するとすぐに上書きされる可能性があります。

ここでスタック オブジェクトを使用する場合は、同期を追加して、新しいスレッドが戻るMQStructObj前にコピーできるようにする必要がありExecuteThreadます。

または、通常は、MQStructObj動的に割り当てて、新しいスレッドを残して、余暇にクリーンアップすることもできます

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
于 2013-01-15T13:12:28.873 に答える