我想为我的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
代码有什么问题?
为什么在push函数中创建的每个节点都有相同的地址?
当我尝试时,甚至打印语句都会影响最终结果(什么!)?
我删除了行
println!("Printing...");
,输出的最后一行是val: 3
可能运气不好,因为我确实运行了相同的添加和删除行大约10次,如果其添加的输出是垃圾值,通过注释它,输出很好(即最后推送的值,在本例中为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 智能指针找到它,我只想尝试仅使用原始指针。
实际上是在函数块内部创建的变量节点,因此函数执行后,你指向的指针就变成了悬空指针。