I'm trying to complete the challenge of creating an XOR linked list. However, I can't finish it because every time I allocate a node object, it uses the same block of memory as the previous one.
var list = new ListXOR();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
Console.WriteLine("Done.");
class ListXOR
{
private readonly List<Node> _nodes = new();
public void Add(int value)
{
Node node = new(value);
_nodes.Add(node);
unsafe
{
Console.WriteLine("Address of new node {0}", (ulong)&node);
}
}
private class Node
{
public int value;
public Node(int newValue) => value = newValue;
}
}
This code displays in the console something like the following:
Address of new node 849654375800
Address of new node 849654375800
Address of new node 849654375800
Address of new node 849654375800
Done.
You also need to add this to your *.csproj
file.
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Why does this happen? Is there a way to prevent it?
CodePudding user response:
The comments already discuss that the &node
isn't doing what you want - it is returning the address of the local variable, not the object.
However: more importantly, you cannot create an XOR linked list with managed objects: you are required to only talk references, because the GC needs to be able to walk the managed heap to detect dead objects, and the GC reserves the right to move objects and fixup references. If you were able to obtain and store a XOR'd reference, you'll break the GC. You can obtain unsafe/unmanaged pointers to managed objects and values, but those pointers are only valid within a defined scope - either within a fixed
block (which you can't do here), or via a GC "pin", and you don't want to allocate a GC pin for every node in a linked list.
The premise of what you are trying to do is flawed.
CodePudding user response:
To prevent this, you can create a new variable for each node object. For example, you could change the Add method to the following:
Node node = new Node(value);
_nodes.Add(node);
unsafe
{
Console.WriteLine("Address of new node {0}", (ulong)&node);
}