当memcpy
和target
重叠时,我发现src
定义告诉我们其未定义的行为:
The memcpy() function copies n bytes from memory area src to memory area dst. If dst and src overlap, behavior is undefined.Applications in which dst and src might overlap should use memmove(3) instead.
我有一个简单的程序,如下所示:
static void RotateLeft(bool *In, int len, int loop) {
for(int i = 0;i< 28;i++) {
LOGI("%d -> %d", i, In[i]);
}
bool Tmp[256] = {0};
memcpy(Tmp, In, loop);
memcpy(In, In + loop, len - loop);
LOGI("len = %d, loop = %d", len, loop); // <--- always 28 and 1
for(int i = 0;i< 28;i++) {
LOGI("%d -> %d", i, In[i]); <----- broken
}
memcpy(In + len - loop, Tmp, loop);
}
RotateLeft(`bool array`, 28, 1)
奇怪的是,这个程序在arm64-v8a
平台上无法正常工作(但在其他平台上运行良好):
输入数组是这样的:
0 0 0 1 1 1 1 0 1 0 0 1 0 1 ...
旋转的数组应为:
0 0 1 1 1 1 0 1 0 0 1 0 1 0...
但实际上是输出:
0 0 1 1 1 1 0 1 0 0 1 1 0 0 ...
以下是该程序如何分配数组:
bool K[64], *KL=&K[0], *KR=&K[28];
// do something fill `K`
RotateLeft(KR, 28, 1);
答案 0 :(得分:1)
此代码的基本假设是sizeof(bool)
为1.不幸的是,this answer中解释的C ++标准无法保证这一点。所以你的代码完全依赖于编译器。
因此,只要您可以使用std::copy()
代替memcpy()
。或者在评论中使用std::rotate()
建议的NathanOlivier。
顺便说一下,它是无关的,但如果你想避免未定义的行为,你最好确保loop>=0 && loop<256 && len>=loop
。