_snprintf_s instokes [peceraiton] .exe触发了断点

_snprintf_s invokes [applicaiton].exe has triggered a breakpoint

本文关键字:断点 exe peceraiton snprintf instokes      更新时间:2023-10-16

_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-围绕变量"缓冲区"堆叠为 损坏。

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

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

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

您不是将buffer发送到_snprintf_s,而是发送&buffer[i * 2]。每次增量,&buffer[i * 2]的可用大小都会降低2。因此,更改为第二个参数,如下:

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