代码之家  ›  专栏  ›  技术社区  ›  Michel Feinstein

memcpy中的指针算法有奇怪的结果[重复]

  •  0
  • Michel Feinstein  · 技术社区  · 5 年前

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

    我有以下资料:

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

    哪里:

    • dest source MyEnum 大小不一,
    • 是64字节长。
    • 来源 是16字节长。
    • sizeof(MyEnum) 4 字节
    • source_size ,因为数组中有4个枚举。

    我把代码循环4次,前进 start_position 每次,在4个循环迭代中的每一次 memcpy 正在使用以下值调用(我已使用调试器对此进行了检查):

    1. memcpy(dest + (0), source, 16); ( 起始位置 =0*4,因为 来源 尺寸是4)
    2. memcpy(dest + (16), source, 16); ( 起始位置 =1*4,因为 来源 尺寸是4)
    3. memcpy(dest + (32), source, 16); ( 起始位置 =2*4,因为 来源 尺寸是4)
    4. memcpy(dest + (48), source, 16); ( 起始位置 =3*4,因为 来源 尺寸是4)

    曼皮西 在第一个循环中运行良好,但在第二个循环中,它会将数据复制到另一个数组中,这显然超出了 数组,侵犯另一个数组的内存区域。

    所以我检查了在我的函数中发生的指针算法,这就是我得到的:

    • 地址是 0xbeffffa74
    • dest + (start_position * sizeof(MyEnum)) 0xbefffab4 对于 (start_position * sizeof(MyEnum) = 16
    • 违反的数组位于 0xBeFFAB4 .

    虽然这解释了为什么数组的内存被破坏,但我不知道 0xbeffffa74 + 16 将会是 0xBeFFAB4 ,但我可以确认这是 曼皮西 正在被呼叫。

    我在用覆盆子皮做这个,但这不重要。

    1 回复  |  直到 5 年前
        1
  •  2
  •   Sami Kuhmonen    5 年前

    指针算法对指针数据类型的大小起作用。如果你有 char* 当指针递增一次时。如果它是 int* 然后每增加一个以上,通常是4到指针(由于int通常是32位的,但不总是)。

    如果有指向结构的指针,则递增该指针会将其移动到结构的大小。因此 sizeof 不应该在那里,否则你会走得太远。

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

    这将在每个位置移动指针4*4字节,因为 MyEnum 是四个字节。

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

    一次只能移动4个字节。

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