首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Memcpy可读区

Memcpy可读区
EN

Stack Overflow用户
提问于 2015-08-21 15:40:00
回答 3查看 422关注 0票数 1

小码位:

代码语言:javascript
复制
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的位?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-21 16:01:53

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

如果双击警告,就可以得到触发此警告的行的高亮显示。

但是您编写的代码是正确的,所以您不必担心这里的结果。在线文档上写着“可能”不会“会”:

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

附加备注:

当使分析器所发生的事情变得更加明显时,它仍然会带来同样的滥用警告:

代码语言:javascript
复制
    memset(buf, '0', 16);
    memset(buf + 16, 0x00, 2);  // for replacing the loop

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

即使是这种过度防范的代码也会发出警告:

代码语言:javascript
复制
    memset(buf, 0x00, sizeof(buf));   // completeky initalize the buffer
    memset(buf, '0', 16);             // overwrite just the beginning

在这里,当memxxx()操作以缓冲区的开始为目标时,该操作的长度被认为是唯一初始化的部分。

所以,是的,警告是烦人的,但是相信你的代码。我只能通过编写一种非常奇怪的低效率编码来消除警告:

代码语言:javascript
复制
    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 

不幸的是,分析器的配置不允许只禁用这一条规则,而是禁用一整套安全验证规则。

票数 2
EN

Stack Overflow用户

发布于 2015-08-21 15:45:53

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

票数 0
EN

Stack Overflow用户

发布于 2015-08-21 15:58:06

你在初始化16个字节。你可以访问18个字节。它似乎认为,访问是阅读,尽管它不应该。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32144349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档