sicp.io
5.3.1 · 벡터로 나타낸 메모리

순서쌍은 나란한 car·cdr 벡터를 가리키는 주소가 될 수 있다.

고정 용량의 두 벡터에 순서쌍 셀을 할당하고 참조를 명시적인 포인터로 나타내어 호스트 순서쌍을 표현 힙으로 쓰지 않고 목록 순서와 변경과 공유 꼬리를 관찰합니다.

생각해 볼 질문

순서쌍이 호스트 pair가 아니라 정수 주소로 표현되어도 car와 cdr와 변경과 공유를 어떻게 유지할까요?

  • 순서쌍 포인터와 원자 데이터를 구분하기
  • 나란한 car·cdr 벡터의 같은 슬롯 할당하기
  • 포인터 인덱스로 car, cdr, set-car!, set-cdr! 구현하기
  • 유한한 목록을 벡터 메모리에 만들고 다시 읽기
  • 서로 다른 두 셀이 표현된 꼬리 하나를 공유하는 모습 관찰하기
  • 무한 메모리를 가정하지 않고 용량 소진을 드러내기

메모리 객체는 길이가 같은 벡터 두 개와 free 인덱스 하나를 가집니다. 표현된 순서쌍은 (ptr index)이고 memory-car와 memory-cdr는 두 벡터의 같은 인덱스를 읽습니다. list->memory는 꼬리를 먼저 만들므로 (a b c)의 루트는 세 셀 중 마지막 주소가 됩니다.

공유 예제는 꼬리 하나를 할당한 뒤 서로 다른 바깥 셀 두 개의 cdr에 같은 포인터를 저장합니다. 그 포인터의 car 슬롯 하나를 바꾸면 두 목록의 관찰이 함께 바뀝니다. 고정 벡터 용량과 계속 증가하는 free 포인터는 수집기가 살아 있는 셀을 다시 배치하기 전까지 명시적인 한계로 남습니다.

SICP 코드UTF-8 2,879 / 1,048,576바이트
예제
결과
출력
진단
실행 추적0 / 0 개 이벤트
    실행은 브라우저 안에서 이루어지며 프로그램 결과와 실행 추적을 보여줍니다.
    예상 결과

    목록 할당은 (3 (ptr 2) (a b c) a b c (c b a) (() (ptr 0) (ptr 1)))을 반환합니다. 공유 실행은 (3 (left changed) (right changed) #t 0)을 반환합니다.

    실행 추적에서 볼 점

    꼬리를 먼저 만들기 때문에 c, b, a가 인덱스 0, 1, 2에 놓이는지 free 포인터를 따라가세요. 공유 실행에서는 바깥 cdr 슬롯 두 개가 같은 (ptr 0)을 담고 car 벡터 슬롯 하나만 바뀌는지 확인하세요.

    직접 해보기

    프로그램을 수정하고 결과를 비교해 보세요.

    마지막 표현 cdr 슬롯만 바꾸는 파괴적 append를 구현하세요. 이어 순환을 만들고 다시 방문한 포인터 인덱스를 보고하는 방문 예산 decoder를 작성하세요.

    힌트 보기

    마지막 셀은 표현된 cdr가 빈 목록인 포인터입니다. 순환 안전 순회는 두 필드를 따라가기 전에 포인터 인덱스를 기억해야 합니다.

    이 수업 완료하기

    이 장의 총 23개 수업 중 0개 완료0%