Rob*_* Lu 1 c pointers bit-manipulation
我需要在最右边的位标记一个int指针的地址,并将该地址存储在某处.例如,0x10处的地址将变为0x11.
我试过了
int* addr = some_pointer;
int* tagged = (int*) (addr | 0x00000001);
Run Code Online (Sandbox Code Playgroud)
但我得到错误:二进制表达式的无效操作数('int*'和'int').我怎么能这样做?
如何将指针的最右位设置为1?
C99/C11提供可选的整数类型,(u)intptr_t
用于将void*
指针转换为整数,然后转换回指针.该往返导致指针的值与原始值相等.它可能具有或不具有与原始指针相同的位模式.
#include <stdint.h>
int i = 42;
int* addr = &i;
void *vptr = addr;
uintptr_t uptr = (uintptr_t) vptr;
// Set least significant bit.
uintptr_t uptr1 = uptr | 1;
// or one-liner
uintptr_t uptr1 = ((uintptr_t) (void *) &i) | 1;
Run Code Online (Sandbox Code Playgroud)
没有打印说明符代码可以转换为最宽的类型以用于显示目的(u)intptr_t
,因此
printf("%p --> %ju --> %ju\n", vptr, (uintmax_t) uptr, (uintmax_t) uptr1);
// or use macros from <inttypes.h>
printf("%p --> %" PRIuPTR " --> %" PRIuPTR "\n", vptr, uptr, uptr1);
Run Code Online (Sandbox Code Playgroud)
只要OP只需要将值存储为整数,就没问题了.(u)intptr_t
源自有效指针的值可以转换回匹配的指针类型,没有任何问题.
到目前为止这么好,但OP可能想要使用被操纵的值.
现在的诀窍是uptr1
可能会或可能不会转换为有效的void *
指针.即使它确实转换为有效 void *
指针,转换为a int *
可能也可能不起作用.这两个步骤超出了C规范 - 未定义的行为.
// UB
void *vptr1 = (void *) uptr1;
printf("%p\n", vptr1);
int *iptr1 = vptr1;
Run Code Online (Sandbox Code Playgroud)
如果代码到目前为止,尝试取消引用这个新指针,它也是UB.
printf("%d\n", *iptr1); // UB, good luck
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
121 次 |
最近记录: |