存在与无效内存访问相关的错误

GO 世界中的绿色环境 - 事实上,这是我在 GO 中的第一个程序。我正在编写一个反转链表的算法,特别是来自这个leetcode。下面的代码片段没有公开我的算法,只公开了我main()用来测试我的实现的函数。调试后,我发现我在此处箭头处失败,并显示错误信息panic: runtime error: invalid memory address or nil pointer dereference。


type ListNode struct {

    Val int

    Next *ListNode

}

func main(){

    var list *ListNode

    head := list

    for i := 0; i <= 5; i++ {

        var dummy *ListNode

        list.Val = i    <--------------------- here

        list.Next = dummy

        dummy = list

    }

    result := reverseList(head)


    for result != nil{

        fmt.Printf("%d\t", result.Val)

    }

}

我真的很感激对这个问题的一些讨论!


慕标琳琳
浏览 162回答 2
2回答

肥皂起泡泡

基本问题是您永远不会为结构指针分配内存。当你写:var list *ListNode您已经创建了一个指向 ListNode 类型的指针,但您实际上并没有为它分配任何内存。所以当你尝试写...list.Val = i您收到“无效内存地址”错误,因为您试图取消引用未定义的指针。分配内存的一种方法是使用new()新的内置函数:var list *ListNode = new(ListNode)您还可以获取结构的地址,如下所示:list := &ListNode{}上面显示了正确的语法,但是如果您只是用var上面的声明替换现有的声明,您的代码中仍然会有逻辑问题:您不想分配任何内存,直到您将第一个节点添加到列表中。这意味着我们要等到我们进入for循环内才能分配内存。通过对您的代码进行一些小的更改,我们得到:package mainimport "fmt"type ListNode struct {&nbsp; &nbsp; Val&nbsp; int&nbsp; &nbsp; Next *ListNode}func main() {&nbsp; &nbsp; var head, tail *ListNode&nbsp; &nbsp; for i := 0; i <= 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; node := new(ListNode)&nbsp; &nbsp; &nbsp; &nbsp; node.Val = i&nbsp; &nbsp; &nbsp; &nbsp; if tail == nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // This is the first node in the list, so just point head&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // and tail at the new node.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tail = node&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; head = tail&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // There is at least one node in the list, so attach the new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // node to the tail&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tail.Next = node&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tail = node&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; result := head&nbsp; &nbsp; for result != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%d\t", result.Val)&nbsp; &nbsp; &nbsp; &nbsp; // Don't forget to increment to the next node!&nbsp; &nbsp; &nbsp; &nbsp; result = result.Next&nbsp; &nbsp; }}运行此代码会产生:0&nbsp; &nbsp; &nbsp; &nbsp;1&nbsp; &nbsp; &nbsp; &nbsp;2&nbsp; &nbsp; &nbsp; &nbsp;3&nbsp; &nbsp; &nbsp; &nbsp;4&nbsp; &nbsp; &nbsp; &nbsp;5

慕桂英4014372

您必须为列表节点分配内存。创建列表节点时,更新前一个节点中的 Next 字段或更新列表头(如果这是第一个节点)。var head *ListNode// p is pointer to head or pointer to previous node's Next.&nbsp;&nbsp;// We start with p set as pointer to the head.p := &headfor i := 0; i <= 5; i++ {&nbsp; &nbsp; // Allocate a new ListNode with Val initialized.&nbsp; &nbsp; n := &ListNode{Val: i}&nbsp; &nbsp; // Update head or previous node'a Next field.&nbsp; &nbsp; *p = n&nbsp; &nbsp; // The next iteration of the loop should update&nbsp; &nbsp; // the Next field in the node that we just created.&nbsp; &nbsp; p = &n.Next}// Loop while list node is not nil.for n := head; n != nil; n = n.Next {&nbsp; &nbsp; fmt.Println(n.Val)}&nbsp; &nbsp;&nbsp;https://go.dev/play/p/qUhza05kUFT
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go