簡體   English   中英

是否可以在Rust中將一個結構的內存與另一個結構關聯?

[英]Is it possible to associate memory from one struct with another in Rust?

我知道,在Rust中,編譯器不能保證您以聲明它們的順序獲取結構數據,以節省內存(我也相信某些C代碼優化器在做同樣的事情)。 假設現在我有一棵二叉樹,想將其轉換為雙鏈表。 在CI中將聲明兩個結構:

typedef struct tree{
    void* left_child;
    void* right_child;
    void* data;
}tree_t;

對於樹,以及:

typedef struct list{
    void* before;
    void* after;
    void* data;
}list_t;

用於鏈接列表。 如果現在我想將樹轉換為列表,則可以就地執行此操作,只需將樹的內存與列表結構相關聯並更改指針:

tree_t mytree;
/*fill tree*/
list_t *list_p;
list_p = (list_t)&mytree;
/*change pointers accordingly*/

但是如何在Rust中做這樣的事情? 如果不使用unsafe代碼,是否有可能? 直到現在我有了我的樹:

struct TreeNode<'a, T> {
    left_child: BinaryTreeLink<'a, T>,
    right_child: BinaryTreeLink<'a, T>,
    data : &'a T,
}

type BinaryTreeLink<'a, T> = Option<Box<TreeNode<'a, T>>>;

列表將是:

struct ListNode<'a, T> {
    before: ListLink<'a, T>,
    after: ListLink<'a, T>,
    data : &'a T,
}

type ListLink<'a, T> = Option<Box<ListNode<'a, T>>>;

但是,現在如何才能有效地將它們轉換為原位?

但是如何在Rust中做這樣的事情? 如果不使用不安全的代碼,是否有可能? 直到現在我有了我的樹

直接執行相同的操作,您將需要使用不安全的代碼。 函數std::mem::transmute完全std::mem::transmute您的需求。 問題是不能保證Rust中的結構布局,因此以下通常是未定義行為:

use std::mem;
let list_link: Option<Box<ListNode<_>>> = unsafe { mem::transmute(tree_node) };

但是,您可以使用C表示形式,通過強制結構的布局可預測來確保其安全性:

#[repr(C)]
struct TreeNode<'a, T> {
    left_child: BinaryTreeLink<'a, T>,
    right_child: BinaryTreeLink<'a, T>,
    data : &'a T,
}

#[repr(C)]
struct ListNode<'a, T> {
    before: ListLink<'a, T>,
    after: ListLink<'a, T>,
    data : &'a T,
}

您還需要申請#[repr(C)]的內部類型的定義ListLinkBinaryTreeLink


但是,如何完全避免使用不安全的代碼呢? 如果編寫使用原始數據的轉換函數,則優化器應該能夠將其變為無操作,因為它知道沒有其他代碼可以引用該內存。

<'a, T> impl From<ListNode<'a, T>> for TreeNode<'a, T> {
     fn from(other: ListNode<'a, T>) -> ListNode<'a, T>> {
         ListNode {
             before: other.left_child,
             after: other.right_child,
             data: other.data,
         }
     }
}

您絕對應該對此進行基准測試以確保,但是優化器擁有將其變為無操作所需的所有信息,而且很有可能會做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM