小码位:
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的位?
发布于 2015-08-21 16:01:53
来自代码分析器的这条消息似乎基于这样的原则:缓冲区内容将单独定义为来自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 不幸的是,分析器的配置不允许只禁用这一条规则,而是禁用一整套安全验证规则。
发布于 2015-08-21 15:45:53
似乎是编译器/ lint工具中的一个bug (取决于谁向您显示警告)。
发布于 2015-08-21 15:58:06
你在初始化16个字节。你可以访问18个字节。它似乎认为,访问是阅读,尽管它不应该。
https://stackoverflow.com/questions/32144349
复制相似问题