小码位:

int main()
{
    char buf[18];
    char buf2[18];
    int newlength = 16;
    memset(buf, '0', 16);
    for (int i = newlength; i < 18; i++)
        buf[i] = 0x00;

    memcpy(buf2, buf, 18);

    return 0;
}

首先,我想将数组的一部分设置为特定值,然后我要用0x00填充其余部分。然后,我想将其复制到另一个数组。

在MS VS2013上,我收到一个警告,指出buf的可读范围在0到15之间。(C / C++警告的代码分析。C6385读取溢出)为什么? memcpy是否忽略设置为0x00的位?

最佳答案

来自代码分析器的此消息似乎基于以下原理:缓冲区内容将单独定义为memset()的输出。它错过了memset()之后的循环完成此输入的要点。

如果双击警告,则会突出显示考虑触发此警告的行。

但是您编写的代码是正确的,因此您不必担心这里的结果。在线文档说“可能”没有“会”:



附加说明:

当使分析器发生的事情更加明显时,它仍然会带来相同的侮辱性警告:

    memset(buf, '0', 16);
    memset(buf + 16, 0x00, 2);  // for replacing the loop

在这种情况下,分析器会注意到第二个memset()。但是由于它从一开始就不会影响buf,因此它是缓冲区操作的输入/输出,而没有考虑额外的长度。

甚至这种过分谨慎的代码也会发出警告:
    memset(buf, 0x00, sizeof(buf));   // completeky initalize the buffer
    memset(buf, '0', 16);             // overwrite just the beginning

在这里,似乎memxxx()操作一旦以缓冲区的开头为目标,该操作的长度就被视为唯一的初始化部分。

因此,是的,警告很烦人,但是请相信您的代码。我只能通过使一个奇怪的低效率编码摆脱警告:
    memset(buf, 0x00, sizeof(buf));   // 18 bytes get initalized
    memset(buf + 1, '0', 15);         // not begin of buffer
    buf[0] = '0';                     // not a memxxx() operation

不幸的是,分析仪的配置不允许仅禁用单个规则,而是禁用整个安全验证规则集。

关于c++ - Memcpy可读范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32144349/

10-10 21:23