请帮助我理解指针值的这种按位操作

时间:2011-04-26 21:42:47

标签: c++ c bit-manipulation

我无法理解为什么addr被长时间类型化,然后用表达式补充..基本上涉及peekAddr计算的整行

void *addr;
char *peekAddr ;
peekAddr = (char *) ((long)addr & ~(sizeof(long) - 1 ) ) ;
peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;

5 个答案:

答案 0 :(得分:5)

sizeof (long)     = (0)00000100
sizeof(long)-1    = (0)00000011
~(sizeof(long)-1) = (1)11111100

所以2位设置为0使地址对齐为4个字节。另外,当地址已经增加sizeof(long)-1

时,它主要被使用

答案 1 :(得分:4)

它被转换为long,因为(1)你不能对void*进行任何操作,除非在作者的平台上施放它和(2),void*值只是如此恰好适合long。他应该真的使用过uintptr_tsize_t

这段代码的作用是什么:

sizeof(long) - 1

很可能是3或7,具体取决于平台。

~(sizeof(long) - 1)

是一个位掩码,可以选择除最后几位之外的所有位。

((long)addr & ~(sizeof(long) - 1))

向下舍入/对齐addr以寻址long大小的块。舍入发生是因为最后的lg(3)或lg(7)位为零,而其余位从addr复制(其中lg是整数二进制对数)。

答案 2 :(得分:3)

这是一种非常丑陋,不可移植的做法

peakAddr = (char *)addr - ((uintptr_t)addr & -(uintptr_t)sizeof(long));

请注意,原始版本不仅依赖于指向long和返回的指针的成功往返转换,还取决于size_tsizeof运算符的结果类型)宽度相同或宽于long。如果不是,则使用~生成的位掩码将在高位中零扩展并消除指针的一部分。

基本上,你应该记住,你发现的任何程序都是错误的代码,而不是把它作为思想的来源......

答案 3 :(得分:1)

你基本上使peekAddr始终在sizeof(长)地址上对齐。该行生成一个位掩码和二进制文件,并将其设置为查看地址。 该行从peekAddr中删除最后一个sizeof(long)-1位。

HTH

马里奥

答案 4 :(得分:1)

这会在sizeof(long) < sizeof(char*)的某些编译器上出现错误,例如Microsoft的。

sizeof(long)-1正在创建与long大小相对应的位掩码。这是一个仅适用于2的幂的数字的技巧。前面的~反转它,所以现在它是所有地址位的掩码,当你试图对齐地址时它应该保持不变。按位&正在清除地址的底部位以使其对齐。