C++のUnicodeプロジェクトにおいて、_wgetenvでWindowsの環境変数が取得できるのはわかる。
こんなソースがあって、ビルドしたらエラーになった。
void CMFCApplication1Dlg::OnBnClickedButton2() { TCHAR* buffer; buffer = _wgetenv(_T("PATH")); AfxMessageBox(buffer); }
error C4996: ‘_wgetenv’: This function or variable may be unsafe. Consider using _wdupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
ようするに、セキュリティ付きの関数である_wdupenv_sを使わないとダメだよということ。
プロジェクトのプロパティ⇒C/C++⇒全般⇒SDLチェックを「いいえ」にすればワーニングで済む。
さらにはワーニングの4996を無視してしまえば、ワーニングすら出ないようにすることはできる。
それも気持ち悪いので、セキュリティ対応した_wdupenv_sの使い方を記録しておく。
void CMFCApplication1Dlg::OnBnClickedButton1() { TCHAR* buffer = NULL; size_t requiredSize = 0; _wgetenv_s(&requiredSize, NULL, 0, _T("PATH")); if (requiredSize == 0) { AfxMessageBox(_T("error")); return; } buffer = new TCHAR[requiredSize]; _wgetenv_s(&requiredSize, buffer, requiredSize, _T("PATH")); AfxMessageBox(buffer); delete buffer; }
久しぶりにコメントします。
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/dupenv-s-wdupenv-s?view=vs-2017
Notes
It is the calling program’s responsibility to free the memory by calling free.
と書いてあるので、_wdupenv_s()自体が、戻り値をコピーするバッファの割り当てを行うみたいなので、自前でnew しないで、メモリを解放すれば良いみたいですね。
_wdupenv_sじゃなくて、_wgetenv_sなのでちょっと違う感じですね。わざわざメモリーサイズ取得して、メモリー取得して、さらにメモリー破棄しないといけないわけで、チョーメンドウですよ。セキュリティ対策前の_wgetenvは何もしなくてよかったんですけどね。
https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/getenv-s-wgetenv-s?view=vs-2017
失礼しました。
メモリ管理は、C++,C言語の宿命ですからね。