2

コードでこれらのワイド文字リテラルを使用して、それらについて学習しています。

     wchar_t* wpsub = wcstok(names, names_delim);
     wpsub = wcstok(NULL, names_delim);
     wchar_t* wcopied=new wchar_t[wcslen(wname) + 1];
     strcpy(nameptr, "singh");
     wcscpy(wcopied, wname);
     wcscat(wcopied, L" Singh");

なぜ私はこれらの警告を受け取っているのですか、とにかくそれを無視しました。そのような警告を無視する必要がありますか?

    : warning C4996: 'wcstok': This function or variable may be unsafe. Consider using wcstok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    : see declaration of 'wcstok'
    : warning C4996: 'wcstok': This function or variable may be unsafe. Consider using wcstok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    : see declaration of 'wcstok'
    : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    : see declaration of 'strcpy'
    : warning C4996: 'wcscpy': This function or variable may be unsafe. Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    : see declaration of 'wcscpy'
    : warning C4996: 'wcscat': This function or variable may be unsafe. Consider using wcscat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    : see declaration of 'wcscat'
4

3 に答える 3

2

std::wstringこれらの関数の代わりに、および類似の C++ 標準ライブラリ関数を使用する必要がありますstd::string。これらの関数は、バッファー オーバーランやその他のセキュリティ (アプリケーションの信頼性は言うまでもありません) の問題の影響を受けやすいためです。

于 2011-05-15T10:54:39.697 に答える
2

元のstrtok ファミリ関数を使用しない別の理由があります。

[...] ただし、単一のスレッド内で、これらの関数のいずれかへの呼び出しをインターリーブすると、データの破損や不正確な結果が生じる可能性が高くなります。異なる文字列を解析する場合は、1 つの文字列の解析を終了してから、次の文字列の解析を開始してください。また、別の関数が呼び出されているループ内からこれらの関数のいずれかを呼び出す場合、危険が生じる可能性があることに注意してください。他の関数がこれらの関数のいずれかを使用してしまうと、インターリーブされた一連の呼び出しが発生し、データの破損が引き起こされます。

その理由はstrtok再入可能ではないからです: 設計時には、コンテキストのリポジトリとしてグローバル変数を使用するのが良い考えであると考えられていました (strtok各関数呼び出しの間のどこで続行するかをどのように覚えていると思いますか?)。

過去は過去であり、何十年も前のコードを判断するべきではありませんが、すべての新しい標準 (C99 が頭に浮かびます) を考えると、この関数がリファクタリングされていないことに今でも驚いています。

少なくとも、 Microsoft によって作成された関数の strtok_s ファミリは、そのためにユーザー提供の変数 (と呼ばれるcontext) を使用します。選択肢がある場合は、製品コードの場合は を使用してstrtok_sください。

クロスプラットフォーム コードを提供する必要がある場合、私のアドバイスは次のとおりです。

  1. 実際の関数への間接として使用される関数を書く
  2. Windows では、strtok_s にリダイレクトします。
  3. 安全な strtok があるプラットフォーム (Google で見つけstrtok_rたもの) で、その関数にリダイレクトします。
  4. 安全な strtok がないプラットフォームでは、独自の strtok を記述してください (難しいことではなく、プログラミングを学ぶ良い練習になります)。

現在、これらの C 関数に代わる C++ があり、std::stringメソッドを組み合わせたり、boost::tokenizerを使用したりできます。

于 2011-05-15T11:22:19.377 に答える
1

wcstokは、バッファオーバーランの悪用の影響を受けやすくなっています。コンパイラは、その脅威に対処する代替バージョンを使用することを推奨しています。

については、MSDNドキュメントの備考を参照してくださいwcstok

渡されるデータを完全に制御できる場合はwcstok、心配する必要はありません。渡されたデータがwcstokユーザーによって提供される可能性がある場合、それはバッファオーバーラン攻撃の可能性を生み出します。

于 2011-05-15T09:37:32.320 に答える