win32環境でのスレッド手続きでのスタック巻き戻しについて調べてみました。
私のテストコードは次のとおりです。
class Dummy
{
public:
Dummy() { wcout << L"dummy ctor" << endl; }
~Dummy() { wcout << L"dummy dtor" << endl; }
};
void InnerFunc()
{
Dummy dm;
while(1)
{
char *buf = new char[100000000];
}
}
unsigned WINAPI ThreadFunc(void *arg)
{
Dummy dm;
try
{
InnerFunc();
}
catch(bad_alloc e)
{
wcout << e.what() << endl;
}
_endthreadex(0);
return 0;
}
void OuterFunc()
{
Dummy dm;
HANDLE hModule;
hModule = (HANDLE)_beginthreadex(0, 0, ThreadFunc, 0, 0, 0);
WaitForSingleObject(hModule, INFINITE);
CloseHandle(hModule);
}
int _tmain(int argc, _TCHAR* argv[])
{
OuterFunc();
wcout << e.what() << endl;
return 0;
}
出力結果:
ダミーctor
ダミーctor
ダミーctor ダミー
dtor
割り当て不良
ダミー dtor
ご存じのとおり、コンストラクタとデストラクタの出力は対になっていません。_endthreadex() は、スレッド ハンドルにシグナルを送信し、スレッドのスタック巻き戻しをスキップすると思います。
_endthreadex() なしで再度テストしたところ、期待どおりの結果を得ることができました。
この場合、スレッドでスタックの巻き戻しが必要な場合、スレッド プロシージャで _endthreadex() を使用するべきではありませんか?