_snprintf_s调用[applicaiton] .exe触发了一个断点

时间:2016-11-26 15:48:44

标签: c++ mfc

_snprintf工作正常。但是为什么_snprintf_s触发了断点。有没有错误/或者我错过了一些非常重要的事情。

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 - 围绕变量'buffer'堆栈   损坏。

 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;
  }

2 个答案:

答案 0 :(得分:2)

_snprintf_s是Microsoft提供的“安全”版本的功能。如果它触发断点,那么你在函数调用中做错了,错误是为了帮助你检测到这个bug。 _snprintf不安全并且偶然起作用(因为它实际上依赖于未定义的行为)。

在这种情况下,您显然为缓冲区传递了错误的长度(第二个参数为函数)。虽然str确实具有HASH_STRING的总长度,但您正在索引到缓冲区(str[i * 2])并返回指向该子缓冲区的指针。显然,子缓冲区的长度不能与总缓冲区的长度相同!

答案 1 :(得分:1)

您没有向buffer发送_snprintf_s,而是发送&buffer[i * 2]。在每个增量处,&buffer[i * 2]的可用大小将减少2.因此,请更改为第二个参数,如下所示:

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