我正在尝试制作一个内存高效的双向链表。该列表存储下一个和前一个地址的XOR,但我在函数XOR
中遇到错误。错误是:
[Error] cast from 'node*' to 'unsigned int' loses precision [-fpermissive]
我的代码是:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
node *next;
}*start,*temp;
node* XOR(node *a,node *b)
{
return (node *)((unsigned int)(a)^(unsigned int)(b));
}
void push(int data)
{
node *a=new node;
a->data=data;
a->next=XOR(start,NULL);
if(start!=NULL)
start->next=XOR(start->next,a);
start=a;
}
void disp()
{
temp=start;
node *prev,*cur;
while(temp)
{
cout<<temp->data<<" ";
if(temp==start)
{
prev=temp;
temp=temp->next;
}
else
{
cur=temp;
temp=XOR(temp->next,prev);
prev=cur;
}
}
}
main()
{
start=NULL;
push(1);
push(2);
push(3);
push(4);
push(5);
push(6);
push(7);
push(8);
}
答案 0 :(得分:3)
unsigned int
不能保证与指针一样大,在许多情况下,指针是64位和unsigned int
32位。因此,在这种情况下,高32位被丢弃,使指针无效。您需要uintptr_t
而不是unsigned int
。
更正后的代码必须首先:
#include <cstdint>
在顶部某处为uintptr_t
以及其他各种有用的类型添加声明,然后更改该行:
return (node *)((unsigned int)(a)^(unsigned int)(b));
要:
return (node *)((uintptr_t)(a)^(uintptr_t)(b));
请查看此处,以便更好地解释uintptr_t和其他类似类型如何工作http://www.cplusplus.com/reference/cstdint/
最后我要提到的是,在大多数现代机器中,xored链表实际上会慢一些,而不是比普通的双链表更快,因为这种技术使得CPU和编译器更难以预测你在做什么并且很好地优化这种效果大于节省空间的速度。
答案 1 :(得分:2)
您应该使用uintptr_t
中定义的#include <cstdint>
。
uintptr_t
的目的是能够保持void*
指针并在不损失精度的情况下转换回来。
使用
uintptr_t XOR(node *a,node *b)
{
return reinterpret_cast<uintptr_t>(a)^reinterpret_cast<uintptr_t>(b);
}
我不会再将其强制转回node*
,直到你最终返回到uintptr_t
为有效指针。
我不相信它很好地定义了当你转换一个没有直接从指针指针强制转换的uintptr_t
时会发生什么。