异或链表

发布于 2024-11-07 02:02:42 字数 596 浏览 0 评论 0原文

我最近发现了下面的链接,我发现它非常有趣。

http://en.wikipedia.org/wiki/XOR_linked_list

  • 通用调试工具 无法遵循 XOR 链,使得 调试比较困难; [1]
  • 内存减少的代价 使用量是代码的增加 复杂性,使维护工作更加繁琐 昂贵的;
  • 大多数垃圾收集方案都会这样做 不适用于这样做的数据结构 不包含文字指针;
  • 指针的 XOR 未定义在 一些上下文(例如,C 语言), 尽管许多语言都提供了一些 之间的类型转换 指针和整数;
  • 如果出现以下情况,指针将不可读 一个人没有遍历该列表 - 因为 例如,如果指向列表的指针 项目包含在另一个数据中 结构;
  • 在遍历列表时,您需要 记住地址 之前访问过的节点 计算下一个节点的地址。

现在我想知道这是否是低级语言独有的,或者在 C# 中是否也可能?

是否有任何类似的选项可以使用 C# 产生相同的结果?

I recently came across the link below which I have found quite interesting.

http://en.wikipedia.org/wiki/XOR_linked_list

  • General-purpose debugging tools
    cannot follow the XOR chain, making
    debugging more difficult; [1]
  • The price for the decrease in memory
    usage is an increase in code
    complexity, making maintenance more
    expensive;
  • Most garbage collection schemes do
    not work with data structures that do
    not contain literal pointers;
  • XOR of pointers is not defined in
    some contexts (e.g., the C language),
    although many languages provide some
    kind of type conversion between
    pointers and integers;
  • The pointers will be unreadable if
    one isn't traversing the list — for
    example, if the pointer to a list
    item was contained in another data
    structure;
  • While traversing the list you need to
    remember the address of the
    previously accessed node in order to
    calculate the next node's address.

Now I am wondering if that is exclusive to low level languages or if that is also possible within C#?

Are there any similar options to produce the same results with C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

苦妄 2024-11-14 02:02:42

TL;DR 我快速编写了一个概念验证XorLinkedList 实现 在 C# 中。

使用 C# 中的不安全代码绝对可以做到这一点。但有一些限制:

  1. XorLinkedList 必须是“非托管结构”,即它们不能包含托管引用
  2. 由于 C# 泛型的限制,链接列表不能是泛型的(即使使用 where T : struct)

后者似乎是因为您无法将泛型参数限制为非托管结构。仅使用 where T : struct 您还可以允许包含托管引用的结构。

这意味着您的 XorLinkedList 只能保存原始值,如整数、指针或其他非托管结构。

我知道, C# 中的低级编程

private static Node* _ptrXor(Node* a, Node* b)
{
    return (Node*)((ulong)a ^ (ulong)b);//very fragile
}

非常脆弱。 C# 指针和 IntPtr 不支持 XOR 运算符(可能是个好主意)。

private static Node* _allocate(Node* link, int value = 0)
{
    var node = (Node*) Marshal.AllocHGlobal(sizeof (Node));
    node->xorLink = link;
    node->value = value;
    return node;
}

之后不要忘记 Marshal.FreeHGlobal 这些节点(实现完整的 IDisposable 模式,并确保将免费调用放在 if(dispose) 块之外。

private static Node* _insertMiddle(Node* first, Node* second, int value)
{
    var node = _allocate(_ptrXor(first, second), value);
    var prev = _prev(first, second);
    first->xorLink = _ptrXor(prev, node);
    var next = _next(first, second);
    second->xorLink = _ptrXor(node, next);
    return node;
}

结论 就

我个人而言,我永远不会在 C# 中使用 XorLinkedList(也许)。当我在 C 中编写非常低级的系统内容(例如内存分配器或内核数据结构)时,在任何其他设置中,存储效率的微小提高确实不值得,因为您不能将其与托管对象一起使用。在 C# 中,它对于日常编程来说几乎没有用处。

而且,即使是主内存,存储也几乎是免费的,如果您使用 C#,您可能不太关心存储,我在某处读到过 CLR 对象头。 40字节,所以这个指针将是你最不担心的;)

TL;DR I quickly wrote a proof-of-concept XorLinkedList implementation in C#.

This is absolutely possible using unsafe code in C#. There are a few restrictions, though:

  1. XorLinkedList must be "unmanaged structs", i.e., they cannot contain managed references
  2. Due to a limitation in C# generics, the linked list cannot be generic (not even with where T : struct)

The latter seems to be because you cannot restrict the generic parameter to unmanaged structs. With just where T : struct you'd also allow structs that contain managed references.

This means that your XorLinkedList can only hold primitive values like ints, pointers or other unmanaged structs.

Low-level programming in C#

private static Node* _ptrXor(Node* a, Node* b)
{
    return (Node*)((ulong)a ^ (ulong)b);//very fragile
}

Very fragile, I know. C# pointers and IntPtr do not support the XOR-operator (probably a good idea).

private static Node* _allocate(Node* link, int value = 0)
{
    var node = (Node*) Marshal.AllocHGlobal(sizeof (Node));
    node->xorLink = link;
    node->value = value;
    return node;
}

Don't forget to Marshal.FreeHGlobal those nodes afterwards (Implement the full IDisposable pattern and be sure to place the free calls outside the if(disposing) block.

private static Node* _insertMiddle(Node* first, Node* second, int value)
{
    var node = _allocate(_ptrXor(first, second), value);
    var prev = _prev(first, second);
    first->xorLink = _ptrXor(prev, node);
    var next = _next(first, second);
    second->xorLink = _ptrXor(node, next);
    return node;
}

Conclusion

Personally, I would never use an XorLinkedList in C# (maybe in C when I'm writing really low level system stuff like memory allocators or kernel data structures. In any other setting the small gain in storage efficiency is really not worth the pain. The fact that you can't use it together with managed objects in C# renders it pretty much useless for everyday programming.

Also storage is almost free today, even main memory and if you're using C# you likely don't care about storage much. I've read somewhere that CLR object headers were around ~40 bytes, so this one pointer will be the least of your concerns ;)

琴流音 2024-11-14 02:02:42

C# 通常不允许您在该级别操作引用,因此不幸的是。

C# doesn't generally let you manipulate references at that level, so no, unfortunately.

删除→记忆 2024-11-14 02:02:42

作为已提出的不安全解决方案的替代方案。

如果您使用数组或列表集合支持链接列表,其中“下一个”和“上一个”而不是内存指针指示数组中的索引,您可以实现此异或,而无需诉诸使用不安全的功能。

As an alternative to the unsafe solutions that have been proposed.

If you backed your linked list with an array or list collection where instead of a memory pointer 'next' and 'previous' indicate indexes into the array you could implement this xor without resorting to using unsafe features.

爱*していゐ 2024-11-14 02:02:42

有多种方法可以在 C# 中使用指针,但只能暂时拥有指向对象的指针,因此在这种情况下不能使用它们。造成这种情况的主要原因是垃圾收集——只要您可以执行异或指针之类的操作并稍后对其进行反异或,GC 就无法知道收集某些对象是否安全。

您可以通过使用一个大数组中的索引来模拟指针来制作非常类似的东西,但是您必须自己实现一种简单形式的内存管理(即,当创建新节点时,我应该将其放在数组中的哪个位置?)。

另一种选择是使用 C++/CLI,它一方面允许您充分灵活地使用指针,另一方面允许您在需要时使用 GC 和访问框架。

There are ways to work with pointers in C#, but you can have a pointer to an object only temporarily, so you can't use them in this scenario. The main reason for this is garbage collection – as long as you can do things like XOR pointers and unXOR them later, the GC has no way of knowing whether it's safe to collect certain object or not.

You could make something very similar by emulating pointers using indexes in one big array, but you would have to implement a simple form of memory management yourself (i.e. when creating new node, where in the array should I put it?).

Another option would be to go with C++/CLI which allows you both the full flexibility of pointers on one hand and GC and access to the framework when you need it on the other.

贱贱哒 2024-11-14 02:02:42

当然。您只需要编写该类的代码即可。 C# 中的异或运算符是 ^
这应该就是开始编码所需的全部内容。
请注意,这将要求代码被声明为“不安全”。请参阅此处:了解如何在c#.

Sure. You would just need to code the class. the XOR operator in c# is ^
That should be all you need to start the coding.
Note this will require the code to be declared "unsafe." See here: for how to use pointers in c#.

一杯敬自由 2024-11-14 02:02:42

在这里进行广泛的概括:C# 似乎已经走上了可读性和干净接口的道路,而不是位摆弄和尽可能密集地打包所有信息的道路。

因此,除非您有特殊需要,否则您应该使用为您提供的列表。未来的维护程序员会为此感谢你。

Making a broad generalization here: C# appears to have gone the path of readability and clean interfaces and not the path of bit fiddling and packing all the information as dense as possible.

So, unless you have a specific need here, you should use the List you are provided. Future maintenance programmers will thank you for it.

眉黛浅 2024-11-14 02:02:42

这是可能的,但是您必须了解 C# 如何看待对象。实例变量实际上并不包含对象,而是指向内存中对象的指针。

DateTime dt = DateTime.Now;

dt 是指向内存中包含 DateTime 方案的结构的指针。

因此,您可以执行这种类型的链表,尽管我不确定为什么您会这样做,因为框架通常已经实现了最有效的集合。作为一个思想实验,这是可能的。

It is possible however you have to understand how C# looks at objects. An instance variable does not actually contain an object but a pointer to the object in memory.

DateTime dt = DateTime.Now;

dt is a pointer to a struct in memory containing the DateTime scheme.

So you could do this type of linked list although I am not sure why you would as the framework typically has already implemented the most efficient collections. As a thought expirament it is possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文