我try 将指针一次向前移动4096个字节,如下所示:

#include <stdint.h>
#include <stdio.h>
void calculate(void* a)
{
    uintptr_t stride = 4096; 
    uint64_t *buff = (uint64_t*)a;
    for (uintptr_t offset = 0; offset < 20000; offset += stride)
    {
        fprintf(stdout, "%s: stride = 0x%x offset = 0x%x buff = %p offset+buff = %p\n", __func__, stride, offset, buff, offset+buff);
    }
}

int main(void)
{
    void* address = 0x7f5b588d1000;

    calculate(address);

    return 0;
}

然而,这是当前的输出:

calculate: stride = 0x1000 offset = 0x0 buff = 0x7f5b588d1000 offset+buff = 0x7f5b588d1000
calculate: stride = 0x1000 offset = 0x1000 buff = 0x7f5b588d1000 offset+buff = 0x7f5b588d9000

如你所见,上面写着:

0x7f5b588d1000 + 0x1000 = 0x7f5b588d9000

为什么这个计算是错误的?结果显然应该是0x7f5b588d2000

推荐答案

指针运算是以指向的类型为单位进行的. 这意味着向类型uint64_t的指针添加stride会将指针向上移动stride个元素,而不是stride个字节,因此指针值增加stride * sizeof(uint64_t).

您应该将buff的类型更改为uint8_t *或简单地更改为unsigned char *.这将使地址上移给定的字节数.

uint8_t *buff = a;

还请注意,不一定要从void *点施法或从void *点施法.

C++相关问答推荐

C:gcc返回多个错误定义,但msvc—不""'

我应该如何解决我自己为iOS编译的xmlsec1库的问题?转换Ctx.first在xmlSecTransformCtxPrepare()之后为空

使用GOTO从多个嵌套循环C继续

SDL 2.0-从数组渲染纹理

在一个小型玩具项目中实现终端历史记录功能

将fget()与strcMP()一起使用不是正确的比较

struct 上的OpenMP缩减

以下声明和定义之间的区别

初始变量重置后,char[]的赋值将消失

如何在C中打印包含扫描字符和整数的语句?

1处的解析器错误:yacc语法的语法错误

如何计算打印二叉搜索树时每行所需的空间?

Valgrind用net_pton()抱怨

";错误:寄存器的使用无效;当使用-masm=intel;在gcc中,但在AT&;T模式

gdb - 你能找到持有内部 glibc 锁的线程吗?

模仿 memmove 的行为

将指针的地址加载到寄存器内联拇指组件中

一元运算符

为什么创建局部变量的指针需要过程在堆栈上分配空间?

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?