首页 > 解决方案 > memcpy 中的指针运算有奇怪的结果

问题描述

几年后我回到了 C 编程,所以我想我有点生疏了,但是我在我的代码中看到了一些奇怪的行为。

我有以下内容:

memcpy(dest + (start_position * sizeof(MyEnum)), source, source_size * sizeof(MyEnum));

在哪里:

我循环这段代码 4 次,start_position每次都前进,所以在 4 次循环迭代中的每一次,我都memcpy被调用以下值(我已经用调试器检查了这个):

  1. memcpy(dest + (0), source, 16);start_position= 0 * 4,因为source大小是 4)
  2. memcpy(dest + (16), source, 16);start_position= 1 * 4,因为source大小是 4)
  3. memcpy(dest + (32), source, 16);start_position= 2 * 4,因为source大小是 4)
  4. memcpy(dest + (48), source, 16);start_position= 3 * 4,因为source大小是 4)

memcpy在第一个循环中工作正常,但在第二个循环中,它将数据复制到另一个数组,显然超出了dest数组的内存区域,违反了另一个数组的内存区域。

所以我检查了函数内部发生的指​​针运算,这就是我得到的:

虽然这解释了为什么数组的内存被侵犯,但我不明白0xbeffffa74 + 16会发生什么0xbefffab4,但我可以确认这memcpy是被调用的地址。

我在 Raspberry Pi 上运行它,但 AFAIK 这应该没关系。

标签: c++carrayspointerspointer-arithmetic

解决方案


指针算法适用于指向数据类型的大小。如果你有一个char*然后你增加指针它会移动一个。如果它是一个,int*那么每个增量都会增加一个以上,通常是 4 到指针(由于 int 通常,但不总是,是 32 位)。

如果您有一个指向结构的指针,那么递增指针会将其移动结构的大小。因此,sizeof不应该在那里,否则你会移动太多。

memcpy(dest + (start_position * sizeof(MyEnum)), source, source_size * sizeof(MyEnum));

由于MyEnum是四个字节,因此每个位置都会移动指针 4*4 字节。

memcpy(dest + start_position, source, source_size * sizeof(MyEnum));

这一次只移动 4 个字节。

这是合乎逻辑pointer[2]的,因为*(pointer + 2)如果指针算术没有隐式地考虑指向的类型大小,那么所有索引也需要,sizeof并且你最终会写很多pointer[2 * sizeof(*pointer)].


推荐阅读