gpt4 book ai didi

c - 使用 memcpy() 将缓冲区的尾部移动到其开头? (重叠)

转载 作者:太空宇宙 更新时间:2023-11-04 02:26:26 24 4
gpt4 key购买 nike

我有二进制文件读取缓冲区,它读取可变长度的结构。在缓冲区末尾附近总会有不完整的结构。我想将这样的缓冲区尾部移动到它的开头,然后在下一次读取文件时读取 buffer_size - tail_len 字节。像这样:

char[8192] buf;
cur = 0, rcur = 0;
while(1){
read("file", &buf[rcur], 8192-rcur);
while (cur + sizeof(mystruct) < 8192){
mystruct_ptr = &buf[cur];
if (mystruct_prt->tailsize + cur >= 8192) break; //incomplete
//do stuff
cur += sizeof(mystruct) + mystruct_ptr->tailsize;
}
memcpy(buf,&buf[cur],8192-cur);
rcur=8192-cur;
cur = 0;
}

应该如果 tail 很小而 buffer 很大,因为这样 memcpy 很可能 不会在单个过程中重叠复制的内存段复制迭代。然而,当尾部变大时听起来有点冒险——大于缓冲区的 50%。

如果 buffer 真的很大并且 tail 也很大那么它仍然应该没问题,因为在单个操作中可以复制多少数据存在物理限制,如果我没记错的话对于使用 vector 单元的现代 x86_64 CPU 来说是 512 字节。我考虑过添加条件来检查尾部的长度,如果它与缓冲区的大小相比太大,则执行简单的逐字节复制,但问题是:

多大太大大到考虑这种重叠memcpy或多或少是安全的。 tail > 缓冲区大小 - 2kb?

最佳答案

根据标准,如果源区域和目标区域重叠,memcpy() 具有未定义的行为。区域有多大或有多少重叠并不重要。未定义的行为永远不能被认为是安全的。

如果您正在编写一个特定的实现,并且该实现定义了某些此类复制的行为,并且您不关心可移植性,那么您可以在这方面依赖您的实现的特定行为。但我建议不要。那将是一个讨厌的错误等待咬那些决定将代码与其他实现一起使用的人。甚至 future 的你。

在这种特殊情况下,可以选择使用专用于此目的的 memmove(),这使得使用 memcpy() 进行赌博变得非常鲁莽。

关于c - 使用 memcpy() 将缓冲区的尾部移动到其开头? (重叠),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50401263/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com