如何确定两个指针是否指向同一内存块
How to determine if two pointers point to the same block of memory
我正在尝试解决以下问题:
/*
* Return 1 if ptr1 and ptr2 are within the *same* 64-byte aligned
* block (or word) of memory. Return zero otherwise.
*
* Operators / and % and loops are NOT allowed.
*/
/*
我有以下代码:
int withinSameBlock(int * ptr1, int * ptr2) {
// TODO
int temp = (1 << 31) >> 25;
int a = ptr1;
int b = ptr2;
return (a & temp) == (b & temp);
}
有人告诉我,这正确地解决了问题,但我不确定它是如何工作的。具体来说,线路int temp = (1 << 31) >> 25;
如何帮助解决问题?
行:
int temp = (1 << 31) >> 25;
不正确或触发未定义的行为(取决于单词大小(。碰巧你的机器和编译器上的未定义行为做了正确的事情恰好给出了正确的答案。为了避免未定义的行为并使代码更清晰,您应该使用:
int withinSameBlock(int * ptr1, int * ptr2) {
uintptr_t temp = ~(uintptr_t)63;
uintptr_t a = (uintptr_t)ptr1;
uintptr_t b = (uintptr_t)ptr2;
return (a & temp) == (b & temp);
}
我不确定你从哪里得到的代码(作业?(,但这太可怕了。1.将指针指向int并进行算术运算通常是非常糟糕的做法。实际大小是由这些基元类型定义的,例如,它在指针或int
不是32位的每个体系结构上都会中断。
你应该使用uintptr_t
,它通常大于或等于指针的大小(除了ambigus规范允许的理论拱形(
例如:
#include <stdint.h>
#include <stdio.h>
int withinSameBlock(int * ptr1, int * ptr2) {
uintptr_t p1 = reinterpret_cast<uintptr_t>(ptr1);
uintptr_t p2 = reinterpret_cast<uintptr_t>(ptr2);
uintptr_t mask = ~ (uintptr_t)0x3F;
return (p1 & mask) == (p2 & mask);
}
int main() {
int* a = (int*) 0xdeadbeef;
int* b = (int*) 0xdeadbeee;
int* c = (int*) 0xdeadc0de;
printf ("%p, %p: %dn", a, b, withinSameBlock(a, b));
printf ("%p, %p: %dn", a, c, withinSameBlock(a, c));
return 0;
}
首先,我们需要清楚的是,代码只适用于指针为32位、int
也是32位的系统。在64位系统上,代码会失败得很惨。
左移位CCD_ 5设置CCD_ 6的最高有效位。换句话说,线
int temp = (1 << 31);
与相同
int temp = 0x80000000;
由于int
是一个有符号的数字,所以最高有效位是有符号位。将带符号数字向右移位会将带符号位复制到低阶位中。因此,向右移动25次会导致在高26位中具有1
的值。换句话说,线
int temp = (1 << 31) >> 25;
与相同(如果写成会更清楚(
int temp = 0xffffffc0;
线路
return (a & temp) == (b & temp);
比较a
和b
的高26位而忽略低6位。如果高位匹配,则a
和b
指向相同的存储器块。
假设32位指针,如果这两个指针在同一个64字节的内存块中,那么它们的地址将仅在6个最低有效位中变化。
(1 << 31) >> 25
会给你一个看起来像这样的位掩码:
11111111111111111111111111000000
a=ptr1
和b=ptr2
将a
和b
设置为等于作为存储器地址的指针的值。temp
与这些地址中的每一个(即a&temp
和b&temp
(的逐位AND将屏蔽由a
和b
保持的地址的最后6位。如果剩下的26位是相同的,那么原始地址必须在64字节内。
演示代码:
#include <stdio.h>
void main()
{
int temp = (1 << 31) >> 25;
printf("temp=%xn",temp);
int p=5, q=6;
int *ptr1=&p, *ptr2=&q;
printf("*ptr1=%x, *ptr2=%xn",ptr1, ptr2);
int a = ptr1;
int b = ptr2;
printf("a=%x, b=%xn",a,b);
if ((a & temp) == (b & temp)) printf("truen");
else printf("falsen");
}
- 我在 IDA 或 dbg 或 olly 上看到的内存是否与我在 RAM 上实时加载的内存相同?
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- 本地分配的内存是否可以用于将来使用?
- 多次分配内存是否一次性需要更多时间?
- 删除矢量的尾部(通过擦除)内存是否有效
- 如何找出内存是否属于堆或堆栈
- C++:提升:托管共享内存是否需要信号量锁
- 在 C/C++ 中在特定地址边界上对齐内存是否仍能提高 x86 性能?
- 检查内存是否在堆上
- C++内存 - 是否需要删除使用 'new' 创建的基元类型变量?
- 如果通过委托给“malloc”的重载“new[]”分配,“释放”内存是否安全
- 分配给 cpp 中定义的全局静态变量的内存是否在 C++ 中删除其类的实例后释放
- 我的 265GB RAM 笔记本电脑上的内存是否超过 8GB
- 在动态内存分配中,在程序终止并且忘记释放内存后,该内存是否保持分配状态
- 这些二维数组(C++)的内存是否不足
- 如果我在 for 中声明一个对象,它的内存是否会在那之后被释放?
- 二进制搜索树(如何在插入时检查内存是否不足)
- 用new重新分配内存是否安全
- 在构造函数初始化列表中分配内存是否存在任何问题
- 内存映射内存是否可能