CreateProcessの罠
Advanced Windows 第5版 上をパラパラ見てたら普通にハマりそうなものを見つけたので実際に試してみた。
CreateProcessの第2引数がPCTSTR(const文字列)ではなくPTSTR(非const文字列)になっていて、内部では引数の文字列を変更すると書かれている。
なのでこの引数に読み取り専用領域を渡すとアクセス違反が発生するらしい。
早速Visual Studio 2008で実験。
(なお2008より古いコンパイラはこのコードでも読み取り専用領域に文字列を確保しないため動作するらしい)
#include <windows.h> #include <tchar.h> #include <stdio.h> #include <locale.h> //_tsetlocale用 int _tmain(int argc, _TCHAR* argv[]) { _tsetlocale( LC_ALL, _T("Japanese") ); //_tprintfで日本語を表示させるために必要 STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; PTSTR ::CreateProcess(NULL, _T("notepad"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); return 0; }
これを実行すると
確かにアクセス違反が発生した。
回避策としては一時バッファにコピーしてそれを使えということのようだ
#include <windows.h> #include <tchar.h> #include <stdio.h> #include <locale.h> //_tsetlocale用 int _tmain(int argc, _TCHAR* argv[]) { _tsetlocale( LC_ALL, _T("Japanese") ); //_tprintfで日本語を表示させるために必要 STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; TCHAR szCommandLine[] = _T("notepad"); //一時バッファ ::CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); return 0; }
これで動作OK。
ちょっとした注意点ですね。