2016-11-26 38 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; 
} 

第二個變體提供了相同的結果。 _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是功能的Microsoft提供的 「安全」 的版本。如果它觸發了一個斷點,那麼你在函數調用中做了一些錯誤,並且該錯誤旨在幫助你檢測該錯誤。 _snprintf是不安全的並且意外工作(因爲它實際上依賴於未定義的行爲)。

在這種情況下,您明確地將錯誤的長度傳遞給緩衝區(函數的第二個參數)。雖然str的確的總長度爲HASH_STRING,但您正在索引緩衝區(str[i * 2])並返回指向該子緩衝區的指針。顯然,子緩衝區的長度不能和總緩衝區的長度相同!

+0

如果與第一實施去你是正確的,但對第二個執行什麼。使用sizeof(buffer)的地方,但是錯誤是堆棧緩衝區被破壞。 snprintf不是偶然的工作。我想我在_s變種snprintf中缺少了一些東西。 – Rahul

+0

同樣的問題,當然。當你執行'_countof(buffer)'時,你仍然在傳遞整個緩衝區的大小,但是你只是將一個指針傳遞給緩衝區中的一個子字符串。你正在對'_snprintf_s'函數說謊它正在給出的緩衝區的實際長度。是的,'_snprintf'仍然完全是偶然的。它只是沒有檢查'_snprintf_s'的錯誤,所以它無法捕捉錯誤。 @rahul –

+0

你是對的,正如@BamakShmirani指出的,緩衝區的實際大小必須在每次循環執行時遞減。有一件重要的事情需要集中,請注意 – Rahul

相關問題