memcpy 中的指针运算有奇怪的结果

Pointer arithmetic in memcpy has weird result

几年后我又回到了 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 上,但据我所知,这不重要。

指针运算适用于指向的数据类型的大小。如果你有一个 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)].