6

私がこのようなことをしようとすると:

char* prefix = "Sector_Data\\sector";
char* s_num = "0";
std::strcat(prefix, s_num);
std::strcat(prefix, "\\");

などなど、警告が表示されます

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.

strcatが安全でないと見なされるのはなぜですか?strcat_sを使用せずにこの警告を取り除く方法はありますか?

また、警告を取り除く唯一の方法がstrcat_sを使用することである場合、それはどのように機能しますか(構文的に:明らかに2つの引数を取りません)。

4

7 に答える 7

29

C ++を使用している場合は、混乱を避けてを使用してみませんかstd::string。エラーのない同じ例は次のようになります。

std::string prefix = "Sector_Data\\sector";
prefix += "0";
prefix += "\\"

バッファサイズなどを気にする必要はありません。また、を使用するAPIがある場合は、メンバーconst char *を使用できます。.c_str()

some_c_api(prefix.c_str());
于 2009-06-01T20:33:03.340 に答える
27

バッファprefixは、コピー先よりもスペースが少なく、バッファオーバーランが発生する可能性があるためです。したがって、ハッカーは特別に細工された文字列を渡して、リターンアドレスやその他の重要なメモリを上書きし、プログラムのコンテキストでコードの実行を開始する可能性があります。

strcat_sは、文字列をコピーするバッファの長さを強制的に渡すことでこれを解決します。必要に応じて文字列を切り捨てて、バッファがオーバーランしないようにします。

google strcat_sを使用して、正確な使用方法を確認してください。

于 2009-06-01T20:02:38.843 に答える
5

次を追加することで、これらの警告を取り除くことができます。

_CRT_SECURE_NO_WARNINGS

_SCL_SECURE_NO_WARNINGS

プロジェクトのプリプロセッサ定義に。

于 2009-06-01T20:41:04.290 に答える
4

あなたの場合の宛先文字列(プレフィックス)がその境界を超えて書き込まれるかどうかを確認する手段がないためです。strcatは基本的に、ソース文字列を宛先にバイトごとにコピーしてループすることで機能します。null端子と呼ばれる値「0」(「\ 0」で示される)を検出すると停止します。Cには境界チェックが組み込まれておらず、dest strはメモリ内の単なる場所であるため、strcatは、ソースstrまたはdestを超えても、アドインフィニジウムを継続します。strにはnull端子がありません。

上記のソリューションは、Windows環境に固有のプラットフォームです。プラットフォームに依存しないものが必要な場合は、strncatを使用する必要があります。

strncat(char* dest, const char* src, size_t count)

これは、インテリジェントに使用する場合のもう1つのオプションです。countを使用して、コピーする最大文字数を指定できます。これを行うには、destで使用可能なスペースの量(割り当てた量-strlen(dest))を把握し、それをcountとして渡す必要があります。

于 2009-06-01T20:02:33.370 に答える
4

これは、バッファオーバーランエラーを引き起こす可能性のあるC /C++の文字列操作関数の1つです。

問題は、関数がバッファのサイズを認識していないことです。MSDNドキュメントから:

最初の引数strDestinationは、現在のstrDestinationとstrSourceを組み合わせて、'\0'を閉じるのに十分な大きさである必要があります。そうしないと、バッファオーバーランが発生する可能性があります。

strcat_sは、バッファのサイズを示す追加の引数を取ります。これにより、連結を実行する前にサイズを検証でき、オーバーランを防ぐことができます。http://msdn.microsoft.com/en-us/library/d45bbxx4.aspxを参照してください

于 2009-06-01T20:04:10.183 に答える
4

警告をオフにするには、これを行うことができます。

#pragma warning(disable:4996)

ところで、strcat_s()を使用することを強くお勧めします。

于 2009-06-01T22:58:16.930 に答える
0

strcatには2つの問題があります。まず、関数の外部ですべての検証を実行する必要があります。関数とほぼ同じ作業を実行します。

if(pDest+strlen(pDest)+strlen(pScr) < destSize)

両方の弦の全長を歩いて、ぴったり合うことを確認してから、もう一度全長を歩いてコピーを行う必要があります。このため、多くのプログラマーは、それが適合し、テストをスキップすると単純に想定します。さらに悪いことに、コードが最初に記述されたときに適合することが保証されている可能性がありますが、誰かが別のstrcatを追加したり、プログラム内の別の場所でバッファーサイズや定数を変更したりすると、問題が発生します。

もう1つの問題は、pSrcとpDstがオーバーラップするかどうかです。コンパイラによっては、strcatは、pSrcで一度に1文字ずつ0をチェックする単純なループである可能性があります。pDstがその0を上書きすると、プログラムがクラッシュするまで実行されるループに入ります。

于 2009-06-01T21:15:16.250 に答える