Map is apparently nil even though I already assigned to it

Go version: 1.12.2
Error text: panic: assignment to entry in nil map

I’m aware that assigning to just a var myMap map[string]int leads to an issue with assignment to a nil map and that you have to do myMap := make(map[string]int) but I seem to be having the same issue with a map that I’ve already assigned to. Below is the stripped down code. Beware that I’ve added a bunch of superfluous stuff as a means of troubleshooting (though I tried to rip a lot of that out):


	for frm := range input {

		go func() {
			detMap := make(map[string][]image.Rectangle)
			tmpRect := []image.Rectangle{image.Rectangle{image.Point{0, 0}, image.Point{1, 1}}}
			detMap["init"] = tmpRect
			tmpImg, _, _, _, detMap, sublError = imageFrames.Sublimate(frm)

			rects := det.DetectMultiScale(tmpImg)
			detMap[fname] = rects

			frm.Detections = detMap
			output <- frm
			return
		}()
	}

I added “tmpRect” in an attempt to make sure that detMap is actually not nil. ImageFrames.Sublimate() is below:

func Sublimate(inFrm Frame) (gocv.Mat, string, []byte, map[int]image.Rectangle, map[string][]image.Rectangle, error) {

	retMap := make(map[string][]image.Rectangle)
	retMot := make(map[int]image.Rectangle)

	retMap = inFrm.Detections
	retMot = inFrm.MotionMap

	retMat, err := gocv.NewMatFromBytes(inFrm.Wid, inFrm.Hei, inFrm.Type, inFrm.MatBytes)

	return retMat, inFrm.UserName, inFrm.UserHash, retMot, retMap, err

}

I get the same issue if I just do tmpImg, _, _, _, detMap, sublError := imageFrames.Sublimate(frm) without creating the map beforehand.

Hi @ashinnv
Try to send the current value of the frm to the goroutine. Example:

package main

import (
	"fmt"
	"time"
)

func main() {
	input := []int{2, 4, 6, 8, 10}

	for i := range input {
		go func(x int) {
			processValue(x)
		}(input[i])
	}
	time.Sleep(10)
}

func processValue(value int) {
	fmt.Println(value)
}

link

Or replace “input[i]” with the variable “i”. Otherwise maybe you have a concurrency problem.

package main

import (
	"fmt"
	"time"
)

func main() {
	input := []int{2, 4, 6, 8, 10}

	for i := range input {
		go func(x int) {
			processValue(x)
		}(i)
	}
	time.Sleep(10)
}

func processValue(value int) {
	fmt.Println(value)
}

link 2

1 Like

Which line here is that panic coming from? That should indicate which line has the map access where the map is nil.

Which line?

detMap[fname] = rects

I tried that but still ended up with the same error. I’ve re-written the function to include the lines from Sublimate(), but I’m still getting the issue. I completely removed the anonymous function, as well, so that this is now just a serial loop with just an input chan and an output chan. The new, unstripped version is below:

func detect(input chan okoframe.Frame, output chan okoframe.Frame, classifierLocation string) {

	for frm := range input {

		//go func(frm okoframe.Frame) {
		var tmpImg gocv.Mat
		var sublError error
		//tmpImg, _, _, _, detMap, sublError := okoframe.Sublimate(frm)
		//StartSublimate--------------------------------------------------------------------------------------------
		tmpImg, nmfbError := gocv.NewMatFromBytes(frm.Wid, frm.Hei, frm.Type, frm.MatBytes)
		if nmfbError != nil {
			fmt.Println("Sublimate fail:", nmfbError)
		}

		//END SUBLIMATE---------------------------------------------------------------------------------------

		fname := filepath.Base(classifierLocation)

		fmt.Println("Loading classifier from :", fname)

		det := gocv.NewCascadeClassifier()
		if !det.Load(fname) {
			fmt.Errorf("Couldn't load classifier.")
			os.Exit(1)
		}

		rects := det.DetectMultiScale(tmpImg)
		//detMap[fname] = rects
		frm.Detections[fname] = rects
		//frm.Detections = detMap

		if sublError != nil {
			fmt.Println("Big error with sublimate stuff:", sublError)
			frm.ErrList = append(frm.ErrList, sublError)
		}

		output <- frm
		//return
		//}(frm)
	}
}

This is just weird. I’m sure it’s some stupid little thing I’m completely overlooking, but still, geez.

SOLVED!

The issue was coming from creating the “Frame” type. I create them in a completely different process from images taken from the webcam. These are then encoded and transmitted down a pipeline. When I originally created the Frame type, I created a function that spits out a new frame to be used across the whole project for when I want to create frames, but at this time, I didn’t have the map of opencv detections included.

When I added computer vision to the project, I didn’t update the function that creates blank frames, instead only adding the struct element. This meant that following that, all new frames that were created would have a nil element where the detection map should be.

That frame with a nil detection map would be encoded and sent down the pipeline, where it caused problems in this process. Thanks for all the help and suggestions, guys.

Is this nil? You create retMap in the Sublimate function, but then overwrite it with whatever is in inFrm.Detections and then return that.

EDIT: Oops. I missed that you found out already. Never mind!

1 Like

That came from the thrashing I’d given the source in trying to figure out what was going on. I kept adding and removing stuff in an attempt to get an idea of where the issue was happening. Never considered it wasn’t even in this process at all.