Memcpy 可读范围
Memcpy Readable Range
小码位:
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 的位?
似乎是编译器/lint 工具中的错误(取决于向您显示警告的人)
您正在初始化 16 个字节。您正在访问 18 个字节。它似乎认为访问正在读取,即使它不应该。
来自代码分析器的这条消息似乎是基于缓冲区内容将单独定义为 memset()
输出的原则。它错过了 memset()
之后的循环完成此输入的要点。
如果双击警告,您可以突出显示考虑触发此警告的行。
但是你写的代码是正确的,所以你不用担心这里的结果。在线文档说 "might" 没有 "will" :
This warning indicates that the readable extent of the specified
buffer might be smaller than the index used to read from it.
补充说明:
当让分析器的情况更加明显时,它仍然会带来同样的辱骂性警告:
memset(buf, '0', 16);
memset(buf + 16, 0x00, 2); // for replacing the loop
在这种情况下,分析器注意到第二个 memset()
。但由于它从一开始就不会影响 buf,因此它作为 input/output 进行缓冲区操作而不考虑额外的长度。
即使是这种过于谨慎的代码也会引发警告:
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
不幸的是,分析器的配置不允许只禁用这条规则,而是整套安全验证规则。
小码位:
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 的位?
似乎是编译器/lint 工具中的错误(取决于向您显示警告的人)
您正在初始化 16 个字节。您正在访问 18 个字节。它似乎认为访问正在读取,即使它不应该。
来自代码分析器的这条消息似乎是基于缓冲区内容将单独定义为 memset()
输出的原则。它错过了 memset()
之后的循环完成此输入的要点。
如果双击警告,您可以突出显示考虑触发此警告的行。
但是你写的代码是正确的,所以你不用担心这里的结果。在线文档说 "might" 没有 "will" :
This warning indicates that the readable extent of the specified buffer might be smaller than the index used to read from it.
补充说明:
当让分析器的情况更加明显时,它仍然会带来同样的辱骂性警告:
memset(buf, '0', 16);
memset(buf + 16, 0x00, 2); // for replacing the loop
在这种情况下,分析器注意到第二个 memset()
。但由于它从一开始就不会影响 buf,因此它作为 input/output 进行缓冲区操作而不考虑额外的长度。
即使是这种过于谨慎的代码也会引发警告:
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
不幸的是,分析器的配置不允许只禁用这条规则,而是整套安全验证规则。