인프런 커뮤니티 질문&답변

JUNI님의 프로필 이미지

작성한 질문수

Golang을 통한 백엔드 개발 및 환경 구축하기

서버 메모리 데이터 다루기, Request 바인딩 하기

delete 에러 관련되서 질문이 있습니다.

해결된 질문

23.11.20 21:01 작성

·

245

0

2023/11/20 20:44:01 http: panic serving [::1]:8034: runtime error: invalid memory address or nil pointer dereference

goroutine 51 [running]:

net/http.(*conn).serve.func1()

C:/Program Files/Go/src/net/http/server.go:1854 +0xbf

panic({0xec01a0, 0x126f410})

C:/Program Files/Go/src/runtime/panic.go:890 +0x263

github.com/dev-yakuza/study-golang/gin/start/repository.(*UserRepository).Delete(0xc0000a4030, {0x12466f8, 0x1})

C:/go_gin/src/CURS_SERVICE/repository/user.go:42 +0x36a

github.com/dev-yakuza/study-golang/gin/start/service.(*User).Delete(...)

C:/go_gin/src/CURS_SERVICE/service/user.go:27

github.com/dev-yakuza/study-golang/gin/start/network.(*userRouter).delete(0xc000444530, 0xc000456100)

C:/go_gin/src/CURS_SERVICE/network/user.go:104 +0x1ca

github.com/gin-gonic/gin.(*Context).Next(...)

C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174

github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0005841a0, 0xc000456100)

C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620 +0x66b

github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0005841a0, {0xfeda80?, 0xc00045e0e0}, 0xc000456200)

C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576 +0x1dd

net/http.serverHandler.ServeHTTP({0xfecb10?}, {0xfeda80, 0xc00045e0e0}, 0xc000456200)

C:/Program Files/Go/src/net/http/server.go:2936 +0x316

net/http.(*conn).serve(0xc0004fa090, {0xfee018, 0xc0000a27e0})

C:/Program Files/Go/src/net/http/server.go:1995 +0x612

created by net/http.(*Server).Serve

C:/Program Files/Go/src/net/http/server.go:3089 +0x5ed

관련된 에러가 나고 있습니다.

for index, user := range u.userMap {

if user.Name == userName {

u.userMap = append(u.userMap[:index], u.userMap[index+1:]...)

isExisted = true

continue

}

}

 

해당코드에서 user가 nil일 경우에도 for문이 실행이 되고 있습니다. 혹시 이게 u.userMap이 자동적으로 뒤에 nil이 있는 것으로 확인이 됩니다. 혹시 다른 설정하신게 있으실까요?

아니면 append가 패치된 상황일까요?

일단은
for index, user := range u.userMap {

if user != nil {

if user.Name == userName {

u.userMap = append(u.userMap[:index], u.userMap[index+1:]...)

isExisted = true

continue

}

}

}

이렇게 해결 했습니다.

답변 1

0

July님의 프로필 이미지
July
지식공유자

2023. 11. 20. 22:26

넵 질문주셔서 감사합니다.

일단

runtime error: invalid memory address or nil pointer dereference

이런 에러는 golang을 개발하시면서 흔하게 발생을 하는 에러 입니다. ㅎㅎ

에러 문구처럼 값이 초기화가 되어있지 않을 떄 발생을 해요.

해결하신 코드 방식도 괜찮지만, 좀 더 깔끔하게 수정하는게 좋을꺼같아요.

  • 제가 죄송해요... 강의를 처음촬영해봐서 코드 퀄리티가 너무 떨어지네요 ㅠㅠ

 

기본적으로 userMap이라는 값은 생성된 User들이 들어가는 메모리 변수 입니다.

해당 값에서 for문을 진행을 하시면서, user라는 값이 nil이라는 값이 나오게 된다면, 뭔가 넣는 부분에 문제가 있다고 생각을 합니다.

 

간단하게 코드를 적어보자면 다음과 같아요

type test struct {
    Name string
    Age  string
}

var testMap []*test

testMap = append(testMap, &test{"test one", "3"})
testMap = append(testMap, &test{"abc", "4"})

for index, user := range testMap {
	if user.Name == "test one" {
		testMap = append(testMap[:index], testMap[index+1:]...)
		continue
	}
}

fmt.Println(testMap)

이 코드는 문제가 없이 동작을 합니다.

하지만 이 코드는 문제가 있어서 동작을 하지 않습니다.

type test struct {
    Name string
    Age  string
}

var testMap []*test

testMap = append(testMap, &test{"test one", "3"})
testMap = append(testMap, &test{"abc", "4"})
testMap = append(testMap, nil)

for index, user := range testMap {
	if user.Name == "test one" {
		testMap = append(testMap[:index], testMap[index+1:]...)
		continue
	}
}

fmt.Println(testMap)

왜냐하면 Nil이라는 값은 일반적인 null값입니다.
golang에서는 Null값을 다루는 것을 허용하지 않습니다. 그래서 문제가 발생을 하게 됩니다.

뭔가 create하는 부분에서 Ni이라는 값이 들어가서 발생하는 에러로 추측이 되는데 한번 확인해보시고 추가적인 질문있으면 전달해 주시면 감사하겠습니다.

  • 질문 주신김에 추가로 ㅎㅎ

 

* 표기는 golang에서 포인터를 의미를 합니다.

실제 메모리 주소를 참고한다는 의미라고 생각을 하시면 됩니다.
그래서 *가 사용되는 값에 대해서는 nil이라는 값을 넣을 수 가 있습니다.

실제로 

var testMap []*test

도 []*test로 작성이 되어 있어서 nil을 넣을 수 있었습니다.

하지만 만약 

var testMap []test

로 작성을 하게 되면 nil을 넣을수가 없습니다.

그렇다고 포인터가 나쁜게 아니에요
실무에서는 거의 대부분을 포인터로 사용을 하기 떄문입니다.

이 부분은 golang의 수명주기와 관련이 되어 있는 부분인데

https://codesk.tistory.com/43

이 글 정도 참고해보시면 감이 잡히실꺼 같네요

질문 감사합니다 :)
JUNI님의 프로필 이미지

작성한 질문수

질문하기