ご存知のとおり、strcpy_sはstrcpyの安全バージョンです。
しかし、それがどのように機能するのだろうか...
いくつかの例を見てみましょう。
strpy_sの宣言:
errno_t strcpy_s(_CHAR * _DEST、size_t _SIZE、const _CHAR * _SRC)
eg1
char dest[5];
char* src = "abcdefg";
strcpy_s(dest,5,src);
アサーションを返します。
これは理解できると思います。_ SIZEを使用して、_ SIZEより多くの文字をコピーできないことを確認してください
しかし、私はこれを理解できません。
char dest[5];
char* src = "abcdefg";
strcpy_s(dest,10,src);
それでもアサーションを取得できますが、どのように発生しましたか?
pS、エラーは:
デバッグアサーションに失敗しました
式:(L "バッファが小さすぎます" && 0)
VS2013
strcpy_sは本体内部のdestのサイズをチェックしますか??そして、それがtrueの場合、どのように_DESTのようなポインターをチェックするのですか?
これは実際には、ポインタへの減衰なしに、実行時にスタック配列のサイズを取得する方法です。
template<typename T, size_t N>
size_t arrSize(T (&array)[N])
{
return N;
}
これをテンプレート参照として送信すると、テンプレートメカニズムによってサイズが推定されます。したがって、次のようなことができます
int myArray[10];
cout << arrSize(myArray); // will display 10
だから私の推測では、これが「安全な」MS strcpy_s
はサイズをチェックしています。それ以外の場合、ポインタのみを渡すと、サイズを取得する標準に準拠した方法はありません。
DEBUGモードでは、Microsoft APIはバッファを0xfdで埋めるため、オーバーフローをチェックできます。
この関数はコピーされた文字列を切り捨てませんが、例外を発生させます!
Destバッファーのサイズを指定するのは常に困難です(sizeofではなく_countofを使用)。ほとんどの場合、ポインターを使用するときに!
これらの "_s" APIには、標準のものよりも多くの問題があります!!
dest
は5文字を超えることはできません。そのため、エラーが発生します。 __SIZE
_が原因ではありません。 dest
が_char*
_の場合、十分なメモリを割り当てる必要があります。コンパイルエラーは発生しません。ただし、プログラムでは、dest
のサイズは固定されており、_strcpy_s
_は、strcpy
とは異なり、宛先バッファのサイズをチェックします(可能な場合、この場合は、コンパイル時にサイズが定義されているため、チェックできます)。これを読む
http://www.cplusplus.com/forum/beginner/118771/
基本的に_strcpy_s
_はstrcpy
の「安全な」バージョンであり、オーバーフローすることはできません。標準から:C(2011)およびISO/IEC WDTR 24731-_strcpy_s
_:コピーする前に宛先バッファーサイズをチェックするstrcpy
のバリアント。内部的には、おそらく_strcpy_s
_がsizeof(dest)<SIZE
をアサートします。
[〜#〜] msdn [〜#〜] 「strcpy_s関数は、strSourceのアドレスの内容を、終端のnull文字を含めて、strDestinationで指定された場所にコピーします。宛先文字列は、ソース文字列とその終端のnull文字を保持するのに十分な大きさである必要があります。strcpy_sの動作は未定義ですソースと宛先の文字列が重複している場合。」