Код неправильный - вызов Py_DECREF()
освободил объект, что означает, что pythonList
является висячим указателем, поэтому, когда PyList_Check()
пытается задержать этот указатель, неопределенныйвызывается поведение.
Что касается того, почему это не привело к ошибке сегментации, формальный ответ состоит в том, что неопределенное поведение не должно приводить к каким-либо конкретным наблюдаемым последствиям (таким как ошибка сегментации).Неопределенное поведение может привести к тому, что программа сделает буквально что-нибудь , и программист обязан избегать его вызова.
На практике есть более удовлетворительное объяснение, хотя: на большинстве популярныхВ системах ошибки сегментации возникают, когда программа пытается получить доступ к странице виртуальной памяти, которая не сопоставлена с любым возрастом физической памяти, или сопоставлена с физической страницей, к которой у программы нет доступа.Таким образом, если вы установили pythonList
для указания некоторой случайной / недействительной ячейки памяти, а затем попытались разыменовать ее, вы, вероятно, получите ошибку сегментации.Однако pythonList
не указывает на случайную ячейку памяти, он указывает на ячейку памяти, где находился действительный объект списка Python (вплоть до момента, когда Py_DECREF()
освободил его).«Освобождение» этой памяти просто означает, что структура данных кучи процесса теперь включает эту часть памяти в свой «список свободной памяти» в качестве памяти, которую можно использовать повторно в следующий раз, когда какая-то другая часть процесса захочет выделить память.Он не требует сообщения MMU о том, что эта область памяти теперь недоступна (и вообще говоря, это невозможно, поскольку MMU проверяет действительность памяти страниц , а не отдельных байтов, и это довольно частоиметь страницу памяти, которая содержит как действительные объекты, так и области освобожденной памяти, смешанные вместе).Таким образом, система проверки работоспособности MMU / segmentation-fault не будет отлавливать ваше чтение освобожденной памяти (valgrind может отловить это, но за счет вашей программы, работающей в 10-100 раз медленнее, чем обычно).