Rust 中 LinkedList 中的 Push_back 使用原始指针

问题描述 投票:0回答:1

我想为我的LinkedList编写push_back函数,而不使用递归和使用原始指针(只是为了理解和使用不安全的块)

我的代码:

#[derive(Debug)]
struct Node<T> {
    val: T,
    next: Option<*mut Node<T>>,
}

#[derive(Debug)]
struct LinkedList<T> {
    head: Option<*mut Node<T>>,
}

impl<T> LinkedList<T>
where
    T: std::fmt::Display + std::fmt::Debug,
{
    pub(crate) fn push(&mut self, arg: T) {
        let node = &mut Node {
            val: arg,
            next: None,
        } as *mut Node<T>;
        println!("address of node: {:p}", node);
        unsafe {
            println!("val of node: {:?}", (*node).val);
        }
        if self.head.is_none() {
            self.head = Some(node);
            println!("head set");
            return;
        }
        let mut curr = self.head.unwrap();
        unsafe {
            while let Some(node) = (*curr).next {
                curr = node;
            }
            (*curr).next = Some(node);
        }
    }

    fn print(&self)
    where
        T: std::fmt::Display,
    {
        println!("Printing...");

        let mut curr = self.head;

        while let Some(node) = curr {
            unsafe {
                println!("val: {}", (*node).val);
                curr = (*node).next;
            }
        }
    }
}

fn main() {
    let mut l = LinkedList::<i32> { head: None };

    l.push(20);
    l.push(30);
    l.push(20);
    l.push(3);
    l.print();
}

输出:

address of node: 0xa22e6ffaa0
val of node: 20
head set
address of node: 0xa22e6ffaa0
val of node: 30
address of node: 0xa22e6ffaa0
val of node: 20
address of node: 0xa22e6ffaa0
val of node: 3
Printing...
val: 779090824

代码有什么问题?

  1. 为什么在push函数中创建的每个节点都有相同的地址?

  2. 当我尝试时,甚至打印语句都会影响最终结果(什么!)?

    我删除了行

    println!("Printing...");
    ,输出的最后一行是
    val: 3

    可能运气不好,因为我确实运行了相同的添加和删除行大约10次,如果其添加的输出是垃圾值,通过注释它,输出很好(即最后推送的值,在本例中为3)

  3. 希望我的逻辑是正确的

    除了以递归方式编写之外,任何建议都值得赞赏。

最初我在 cpp 中做了同样的事情,并尝试在 rust 中做同样的事情。 CPP代码:

#include <stdlib.h>
#include <iostream>
using namespace std;
struct Node
{
    int val;
    struct Node *nxt;
};
struct LinkedList
{
    struct Node *head;
};
void push(LinkedList *l, int v)
{
    struct Node *link = (struct Node *)malloc(sizeof(struct Node));
    link->val = v;
    link->nxt = nullptr;
    if (l->head == nullptr)
    {
        l->head = link;
        return;
    }
    auto curr = l->head;
    while (curr->nxt != nullptr)
    {
        curr = curr->nxt;
    }

    curr->nxt = link;
}
void print(LinkedList *l)
{
    auto curr = l->head;
    // cout << curr << endl;
    while (curr != nullptr)
    {
        cout << curr->val << endl;
        curr = curr->nxt;
    }
}
int main()
{
    struct LinkedList *ll = (struct LinkedList *)malloc(sizeof(struct LinkedList));
    ll->head = nullptr;
    push(ll, 2);
    push(ll, 3);
    push(ll, 4);
    print(ll);
    cout << "end" << endl;
    return 0;
}

输出:

2
3
4
end

我能够在 cpp 指针中做到这一点(希望它是正确的方式)或者我很幸运,但我无法在 rust 中做到同样的事情。

我想用指针来做到这一点,我在任何地方都可以使用 Box 智能指针找到它,我只想尝试仅使用原始指针。

rust singly-linked-list
1个回答
0
投票

实际上是在函数块内部创建的变量节点,因此函数执行后,你指向的指针就变成了悬空指针。

© www.soinside.com 2019 - 2024. All rights reserved.