小码位:
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的位?
答案 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个字节。它似乎认为访问是阅读,即使它不应该。