我试着标记和取消标记指针,这样我就可以实现非阻塞链表。我检查了在我的体系结构上最后一位是从来没有使用过的,所以我试着使用change it来标记/取消标记指针。
我尝试执行OR将最后一位设置为1,AND取消设置,AND检查是否设置为1。问题是,当我对指针执行逐位(注解宏)操作时,我无法解引用它。解引用它会导致分段错误,即使指针的整数值是正确的。
更具体地说,#define unmark(x) (x & (uintptr_t) 0xfffffffe)
是导致分段错误的原因。如果我不使用它(而是使用#define unmark(x) x - 1
),程序就能工作。
递增和递减指针看起来是有效的,但它可能使解决方案架构特定。这是因为在我的架构上指针总是以8结尾,它的最后一位设置为0。如果不是这样,我的解决方案将不是非常可移植的。
我知道操纵指针可能无论如何都不是可移植的,但它是这个算法所必需的。如果有人知道是什么导致了这个问题,那就太棒了。
这是我用来测试解决方案的代码:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
//This produces segfault, for some reason
//#define unmark(x) (x & (uintptr_t) 0xfffffffe)
//#define mark(x) (x | (uintptr_t) 0x00000001)
#define is_marked(x) ((long) x & 0x00000001)
#define mark(x) x + 1
#define unmark(x) x - 1
struct Example {
long x;
long y;
};
int main() {
struct Example *x = malloc(sizeof(struct Example));
x->x = 10;
x->y = 20;
uintptr_t p = (uintptr_t)(void*) x;
printf("%ld\n", ((struct Example *) (void*) p)->y);
printf("%04x\n", p);
printf("Is marked: %d\n", is_marked(p));
p = mark(p);
printf("%04x\n", p);
printf("Is marked: %d\n", is_marked(p));
p = unmark(p);
printf("%04x\n", p);
printf("Is marked: %d\n", is_marked(p));
printf("%ld\n", ((struct Example *) (void*) p)->y);
return 0;
}
1条答案
按热度按时间31moq8wy1#
代码有很多问题
不清除最低有效位
x & (uintptr_t) 0xfffffffe
假定uintptr_t
为32位。假设指针的位操作正常
不匹配的说明符
不如
不必要的强制转换