extremely green in the world of GO - infact this is my first ever program in GO. I'm writing an algorithm that reverses a linked list, specifically from this leetcode. The code snippet below doesn't disclose my algorithm, only the main()
function I'm using to test my implementation. After debugging, I found that I fail at the here arrow with the error message 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)
}
}
I would really appreciate some discussion to this problem!
CodePudding user response:
The basic problem is that you're never allocating memory for your struct pointers. When you write:
var list *ListNode
You have created a pointer-to-ListNode type, but you haven't actually allocated any memory for it. So when you try to write...
list.Val = i
You get the "invalid memory address" error, because you're trying to dereference an undefined pointer. One way of allocating memory is to use the new()
new builtin function:
var list *ListNode = new(ListNode)
You can also take the address of a struct, like this:
list := &ListNode{}
The above shows the correct syntax, but if you were to simply replace
your existing var
declaration with the above you would still have
logic problems in your code: you don't want to allocate any memory
until you add the first node to the list. That means we want to wait
until we're inside the for
loop to allocate memory.
With some minor changes to your code, we get:
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func main() {
var head, tail *ListNode
for i := 0; i <= 5; i {
node := new(ListNode)
node.Val = i
if tail == nil {
// This is the first node in the list, so just point head
// and tail at the new node.
tail = node
head = tail
} else {
// There is at least one node in the list, so attach the new
// node to the tail
tail.Next = node
tail = node
}
}
result := head
for result != nil {
fmt.Printf("%d\t", result.Val)
// Don't forget to increment to the next node!
result = result.Next
}
}
Running this code produces:
0 1 2 3 4 5
CodePudding user response:
You must allocate memory for the list nodes. As the list nodes are created, either update the Next field in the previous node or the list head if this is the first node.
var head *ListNode
// p is pointer to head or pointer to previous node's Next.
// We start with p set as pointer to the head.
p := &head
for i := 0; i <= 5; i {
// Allocate a new ListNode with Val initialized.
n := &ListNode{Val: i}
// Update head or previous node'a Next field.
*p = n
// The next iteration of the loop should update
// the Next field in the node that we just created.
p = &n.Next
}
// Loop while list node is not nil.
for n := head; n != nil; n = n.Next {
fmt.Println(n.Val)
}