2016-11-26 1 views
1

_snprintfが正常に機能します。しかしなぜ_snprintf_sがブレークポイントを引き起こしたのですか?何か間違いがあるか、または何か非常に重要なものが欠けている。_snprintf_sが[applicaiton]を呼び出しました.exeがブレークポイントをトリガーしました

std::string hash_sha256_sa(const std::string source) 
{ 
    const int HASH_STRING = 64; 
    const int HASH_RAW = 32; 

    unsigned char _hash[HASH_RAW]; 
    memset(_hash, 0, HASH_RAW); 

    sha256(_hash, (unsigned char*)&source[0], (unsigned long)source.length()); 

    std::string str(HASH_STRING, 0); 

    for (int i = 0; i < HASH_RAW; ++i) 
    { 
     //_snprintf_s(&str[i * 2], HASH_STRING, _TRUNCATE, "%02X", _hash[i]); //Failed 

     //_snprintf(&str[i * 2], HASH_STRING,"%02X", _hash[i]); //Works    
    } 

    return str; 
} 

第2の変形例は、同じ結果を提供する。 _snprintfは正常に動作します。 _snprintf_sはエラーの後に結果を返します

変数 'バッファ'のランタイムチェック失敗2は、 が破損しました。

std::string hash_sha256_sa(const std::string source) 
{ 
    const int HASH_STRING = 64; 
    const int HASH_RAW = 32; 

    unsigned char _hash[HASH_RAW]; 
    memset(_hash, 0, HASH_RAW); 

    sha256(_hash, (unsigned char*)&source[0], (unsigned long)source.length()); 

    char buffer[HASH_STRING + 1]; 

    for (int i = 0; i < HASH_RAW; ++i) 
    { 
     _snprintf_s(&buffer[i * 2], _countof(buffer), _TRUNCATE, "%02X", _hash[i]); 

     //_snprintf(&buffer[i * 2], _countof(buffer), "%02X", _hash[i]); 

    } 

    std::string str(buffer); 
    return str; 
    } 

答えて

1

buffer_snprintf_sに送信するのではなく、&buffer[i * 2]を送信しています。各増分で、&buffer[i * 2]ために利用可能なサイズは、次のように第二パラメータに変更2.によって減少します:

_snprintf_s(&buffer[i * 2], _countof(buffer) - i * 2, _TRUNCATE, "%02X", _hash[i]); 
2

_snprintf_s機能のマイクロソフトが提供する "安全な" バージョンです。ブレークポイントを起動している場合は、関数呼び出しで何か問題があります。このエラーは、そのバグを検出するのに役立ちます。 _snprintfは安全ではなく、実際には未定義の動作に依存しているため、偶発的に動作します。

この場合、バッファの長さが間違っています(関数の2番目のパラメータ)。 strの実際の長さはHASH_STRINGですが、バッファにインデックスを付けて(str[i * 2])、そのサブバッファへのポインタを返します。明らかに、サブバッファの合計バッファと同じ長さを持つことはできません!

+0

最初の実装と一緒に行く場合、あなたは正しいですが、どのような第2の実施について。 sizeof(buffer)が使用されていますが、バッファーの周りにスタックのエラーがあります。 snprintfは偶然には動作しません。私はsnprintfの亜種に何かが欠けていると思います。 – Rahul

+0

もちろん、同じ問題です。あなたは '_countof(buffer)'を実行してもバッファ全体のサイズを引き継いでいますが、バッファ内のサブ文字列へのポインタだけを渡しています。 '_snprintf_s'関数には、与えられているバッファの実際の長さについて嘘をついています。はい、 '_snprintf'はまだ偶然によって完全に動作しています。 '_snprintf_s'がエラーをチェックしていないので、バグを捕まえることができません。 @rahul –

+0

あなたが正しいのは、@BamakShmiraniが指すように、バッファの実際のサイズは、各ループの実行時にデクリメントする必要があります。重要なことがいくつか焦点を当てて残っていますか? – Rahul

関連する問題