Search code examples
goqueueruntime-error

getting error while removing the element from queue


func (t *bt) topview() {
    if t.root == nil {
        return
    }
    qu := list.New()
    topview := make(map[int]*tree)
    qu.PushBack(top{t.root, 0})
    //fmt.Println(sample.Value.(top).hd)
    fmt.Println("top view")
    for qu != nil {
        sample := qu.Front()
        qu.Remove(qu.Front())
        for key := range topview {
            if key != sample.Value.(top).hd {
                topview[sample.Value.(top).hd] = sample.Value.(top).node
            }
        }
        if sample.Value.(top).node.left != nil {
            qu.PushBack(top{sample.Value.(top).node.left, sample.Value.(top).hd - 1})
        }
        if sample.Value.(top).node.right != nil {
            qu.PushBack(top{sample.Value.(top).node.right, sample.Value.(top).hd + 1})
        }
    }
    for _, value := range topview {
        fmt.Println(value)
    }

}

this error I get

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x109e1cf]

goroutine 1 [running]:
container/list.(*List).Remove(...)
    /usr/local/go/src/container/list/list.go:140
main.(*bt).topview(0xc000072f60)
    /Users/pulkitkundra/work/hackerrank/golang-30/tree.go:100 +0x32f
main.main()
    /Users/pulkitkundra/work/hackerrank/golang-30/tree.go:126 +0x108
exit status 2

I tried to put the remove line in defer then it gets stuck. if I don't remove the element it went to infinite loop. I am trying to achieve the top view code for BST. Not looking for to create queue in another way.


Solution

  • panic error is caused by the line

    qu.Remove(qu.Front())
    

    because the element passed to qu.Remove() is nil and this happens because qu.Front() returns nil when the list is empty (i.e. once all elements are removed)

    loop condition

    for qu != nil {
    

    is wrong because it will never be meet since qu will never be nil.

    loop should go "until the list is not empty", i.e:

    for qu.Len() > 0 {
    

    this will prevent qu.Front() from returning nil and in turn to pass it to qu.Remove() and cause panic error.