-2

I'm bit lost with this panic when writing gRPC server in Go

    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x18 pc=0x8c7892]

Here's what I am trying to do, attempting to create a slice of test data :

inputVal := make([]*pb.TableHeader, 1)

        for i := range inputVal {
            inputVal[i].UserDefinedAlias = "myCustomName"
            inputVal[i].Type = "SomeType"
            inputVal[i].Class = "TestClass"
            inputVal[i].ColumnID = "Col12"
            inputVal[i].IsSortable = false
            inputVal = append(inputVal, inputVal[i])
        }

TableHeader has this structure

type TableHeader struct {
    ColumnID             string   `protobuf:"bytes,1,opt,name=columnID,proto3" json:"columnID,omitempty"`
    UserDefinedAlias     string   `protobuf:"bytes,2,opt,name=userDefinedAlias,proto3" json:"userDefinedAlias,omitempty"`
    IsSortable           bool     `protobuf:"varint,3,opt,name=isSortable,proto3" json:"isSortable,omitempty"`
    Type                 string   `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"`
    Class                string   `protobuf:"bytes,5,opt,name=class,proto3" json:"class,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

And trying to process that test data created above using following in an rpc service

inputForProcessing := make([]*dt.TableHeader, len(inputVal))
log.Println("reached here for actual processing ",len(inputForProcessing))
    for i, v := range inputVal {
        inputForProcessing[i].ColumnID = v.ColumnID
        inputForProcessing[i].Class = v.Class
        inputForProcessing[i].Type = v.Type
        inputForProcessing[i].IsSortable = v.IsSortable
        inputForProcessing[i].UserDefinedAlias = v.UserDefinedAlias
        inputForProcessing = append(inputForProcessing, inputForProcessing[i])
    }
sup
  • 105
  • 1
  • 4
  • 17
  • 1
    You probably should revisit how you think about populating slices, because what you have there is incorrect and unconventional. Here are some examples: https://play.golang.com/p/uEn8Ks7maSB – mkopriva May 08 '20 at 15:24
  • @mkopriva thanks for pointing out, indeed your right. – sup May 08 '20 at 15:24

1 Answers1

0

When you call inputVal := make([]*pb.TableHeader, 1), this creates a slice of *pb.TableHeader of size one, but does nothing to initialize that one element. If you print it out, you'll get: [<nil>].

This means that the first (and only) iteration in for i := range inputVal will be with i == 0 and inputVal[i] will be nil. Attempting to set a field on a nil pointer causes the panic you see.

The same goes for inputForProcessing, all elements in the created slice will be nil.

Furthermore, you seem to be trying to append inputVal[i] to inputVal. The given element is already there.

Instead, you probably want something along the lines of:

    inputVal := make([]*pb.TableHeader, 1)

    for i := range inputVal {
        inputVal[i] = &pb.TableHeader{
           UserDefinedAlias: "myCustomName",
           Type: "SomeType",
           etc...
        }
    }
Marc
  • 19,394
  • 6
  • 47
  • 51
  • that is indeed true. However I thought by appending to the slice I should then be able to correctly assign value to each key in that slice. – sup May 08 '20 at 15:01
  • thanks! switching to this worked. But I am still bit confused with your comment about slice element already being there. Shouldn't a newly initialized slice be empty, until values are appended to it? Would really appreciate if you can elaborate on that. – sup May 08 '20 at 15:23
  • The way you invoke `make` is with the length parameter, not the capacity. This initializes a slice with that length (and same capacity). Please see the [tour of Go](https://tour.golang.org/moretypes/13) for details. – Marc May 08 '20 at 15:29
  • @sup when you provide the length argument to the `make` function you're automatically pre-populating it with that many zero-valued elements, say `make([]int, 3)` produces a slice with 3 integers, doing an append to that will add a 4th integer, it will not set the 0th integer. – mkopriva May 08 '20 at 15:30