Ячейки пар фиксированной емкости лежат в двух векторах, ссылки становятся явными указателями, а порядок списков, мутация и общие хвосты видны прямо.
Вопрос для размышления
Как car, cdr, мутация и разделение структуры могут сохраняться, когда пара представляется целочисленным адресом, а не парой хоста?
Представление указателя на пару отдельно от атомарных данных
Выделение соответствующих слотов в параллельных векторах car и cdr
Реализация car, cdr, set-car! и set-cdr! через индексы указателей
Построение и декодирование конечного списка в векторной памяти
Наблюдение двух выделенных пар, разделяющих один представленный хвост
Явное отображение исчерпания емкости вместо предположения о бесконечной памяти
Объект памяти содержит два вектора одинаковой длины и один индекс free. Представленная пара имеет вид (ptr index). Процедуры memory-car и memory-cdr используют этот индекс в параллельных векторах, а операция выделения записывает оба поля и сдвигает free вперед. Процедура list->memory сначала строит хвост, поэтому корнем списка (a b c) становится последняя из трех выделенных ячеек, хотя декодирование восстанавливает исходный порядок.
Пример разделения структуры выделяет один хвост и сохраняет указатель на него в двух разных внешних ячейках. Изменение поля car в хвосте через этот единственный указатель изменяет оба декодированных списка. Это тот же вопрос о структуре графа, что и при разделении пар хоста, но идентичность теперь задается явным адресом. Фиксированная емкость векторов и монотонно возрастающий указатель free остаются явными ограничениями до тех пор, пока менеджер памяти не освободит или не скопирует живые ячейки.
Выделение памяти для списка возвращает (3 (ptr 2) (a b c) a b c (c b a) (() (ptr 0) (ptr 1))). Запуск с разделением структуры возвращает (3 (left changed) (right changed) #t 0).
На что обратить внимание в трассе
Проследите за указателем free и обратите внимание, что c, b и a занимают индексы 0, 1 и 2, так как построение хвоста завершается первым. В запуске с разделением структуры убедитесь, что два внешних слота cdr содержат одно и то же значение (ptr 0) и изменяется только один слот в векторе car.
Попробуйте сами
Измените программу и сравните результат.
Реализуйте деструктивную операцию append для векторной памяти, изменяющую только последний представленный слот cdr. Затем создайте цикл и напишите декодер с бюджетом посещений, который сообщает о повторно посещенных индексах указателей.
Показать подсказку
Последней ячейкой является указатель, чей представленный cdr является пустым списком. Безопасный при наличии циклов обход должен запоминать индексы указателей перед переходом по любому из полей.