LINUX.ORG.RU

[GNU Smalltalk] Забавно падает с сегфолтом.


0

1

Поставил на «посмотреть» GNU Smalltalk.

Пишу в repl:

| dict |
dict := Dictionary new
dict at: 'self' put: dict

Падает с забавными криками:

"Global garbage collection... done, heap compacted"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap compacted"
"Global garbage collection... done, heap grown"
"Global garbage collection... Segmentation fault

Если передавать (dict copy), то всё в порядке.

Прошу объяснить что происходит в первом варианте, когда оно падает.

Тут всё очевидно, Ватсон.

Вы попробуйте все это в файлик написать, последней строчкой добавить

'I am alive!' printNl

и запустить как gst -f thatfile.st

На удивление ничего не упадёт и сия фраза распечатается. А всё вот почему - добавить словарь самого в себя можно, от этого ничего не сломается. Но так как вы работаете с REPL, который печатает результаты выполнения введенных команд, наступает засада.

В REPL словари и прочие коллекции выводятся с содержимым, а для случая словаря, содержащего внутри ключ с ссылкой на самого себя, получаем бесконечный цикл (это сродни проходу по закольцованному связанному списку, например). Естественно, наступает переполнение и виртуальная машина падает.

Во втором случае вы кладете в словарь его копию (на тот момент). Копия словаря на тот момент - пустой словарь, поэтому зацикливания не происходит.

yoghurt ★★★★★
()

> (dict copy)

Кстати, скобки в этом случае можно не ставить, унарные сообщения всегда приоритетнее ключевых, и dict copy будет вычислено до dict at:put:

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Всё понятно.

Кстати, скобки в этом случае можно не ставить, унарные сообщения всегда приоритетнее ключевых, и dict copy будет вычислено до dict at:put:

На глаз не видно сразу who is who, так что так читабельней. Во всяком случае пока.

vladimir-vg ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.