Memcpy可读范围

时间:2015-08-21 15:40:00

标签: c++ arrays memcpy memset

小码位:

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的位?

3 个答案:

答案 0 :(得分:2)

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

如果双击警告,则可以突出显示触发此警告的行。

但是你写的代码是正确的,所以你不必担心这里的结果。在线文档说&#34;可能&#34;没有&#34;将&#34; :

  

此警告表示指定的可读范围   缓冲区可能小于用于读取它的索引。

补充说明:

当对分析仪进行更明显的操作时,它仍会带来相同的滥用警告:

    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 

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

答案 1 :(得分:0)

似乎是编译器/ lint工具中的错误(取决于谁向您显示警告)

答案 2 :(得分:-1)

您正在初始化16个字节。您正在访问18个字节。它似乎认为访问是阅读,即使它不应该。