openlang

재귀 호출을 하면 왜 값이 바뀌나요?

어떻게 이런 일이 생기죠? 뭘 확인해야 할까요?

재귀 함수 visit(board)는 구조체를 받고, 함수 안에서는 incoming이라는 이름으로 씁니다.

nextBoard에는 left와 right라는 슬라이스가 두 개 있습니다. 각 슬라이스에는 label1, label2, bool을 멤버로 갖는 작은 구조체 cell이 들어 있습니다.

visit(incoming) 안의 코드는 이렇습니다:

nextBoard := advance(incoming)

savedInput := incoming

visit(nextBoard)

함수 안에서 visit을 호출하는 곳은 이것뿐입니다.

여기까지가 배경이고, 문제는 이렇습니다. 재귀 깊이 27에서 visit이 호출되어 12단계를 더 내려간다고 합시다. 그런 다음 깊이 27로 돌아옵니다. 이때 incoming이 호출 전 내용과 달라져 있습니다. 이상하게 savedInput도 incoming과 정확히 똑같이 바뀌어 있습니다. nextBoard는 호출 전 그대로입니다.

제가 알고 싶은 건 어떻게 이럴 수 있냐는 겁니다. 이 변수 3개는 모두 함수 범위에 있고 패키지 범위가 아닙니다.

incoming의 변화를 더 설명하면, left와 right 슬라이스의 len은 둘 다 7입니다. right 슬라이스가 돌아올 때 원래의 7번째 원소와 달라져 있습니다?

깊이 27에서 39 사이 어딘가에서 right의 일곱 번째 원소가 left의 일곱 번째 원소로 대체되고 불리언이 뒤집히며, left의 7번째 원소는 삭제되는 것은 압니다. advance(incoming)이라는 함수가 그 변경을 합니다.

정확히 말하면, 깊이 27로 돌아온 incoming의 left는 그대로인데 right는 앞에서 설명한 대로 바뀝니다. 즉 불리언이 뒤집힌 right[6]=left[6]입니다.

슬라이스 안의 슬라이스가 여전히 원본과 공유하는 메모리를 가리키는 게 아닐까 의심됩니다. incoming과 savedInput이 똑같이 바뀌는 이유로는 그것밖에 생각나지 않습니다. 그런데 호출 뒤에 incoming이 왜 조금이라도 달라지는 거죠?

시간 내서 읽어주셔서 감사합니다.

특별히 확인할 게 있나요? savedInput:=incoming이라고 썼을 때의 효과를 제가 잘못 이해하나요? :=도 써보고 savedInput을 먼저 선언한 뒤 =도 써봤습니다.

영어에서 번역원문 보기

이어지는 대화 2

서로의 근거를 따라
  1. 고유 링크

    설명을 따라가기가 어려운데, 동작을 보여주는 코드를 올려주실 수 있나요? 말로 설명하는 것보다 코드 자체가 문제를 더 명확하게 보여줄 겁니다.

    영어에서 번역원문 보기
  2. 고유 링크

    맞는 말씀입니다 - 문제를 다시 생각해 보고 예제 코드를 넣어 질문을 다시 올렸습니다. Go - 인자는 값으로 전달되는 줄 알았습니다를 봐주세요

    영어에서 번역원문 보기

같은 질문의 다른 갈래

  1. 같은 sink 호출인데 한 번은 복사, 한 번은 이동

    Nim 2는 복사냐 이동이냐를 호출 지점마다 정한다. proc 단위로 정하지 않는다. 같은 인자, 같은 proc. 첫 호출은 a가 아직 쓰이니 복사한다. 둘째 호출은 이동한다. 호출 지점에는 어느 쪽인지 아무 표시가 없다.…

    답글 2최근 활동 nim
  2. 정리 블록이 실제로 실행될 때까지 가변 빌림을 미루기

    Rust에서 Java의 try { ... } finally { ... }와 비슷하게 패닉에도 안전한 구조를 만들고, try와 finally 블록이 같은 값을 각각 가변으로 빌리게 하려면 어떻게 해야 하나요? 원하는 건 정상…

    답글 2최근 활동 rust
  3. 포인터를 통해 문자 배열 입력받기

    키보드에서 char 배열들로 입력을 받으려고 하면 프로그램이 계속 죽습니다. 키보드에서 char 배열을 읽어서 저장하는 간단한 방법이 뭘까요?

    답글 2최근 활동 c