#python #python-c-api
#python #python-c-api
Вопрос:
Будет ли интерпретатор Python освобождать память объекта, если его количество ссылок отрицательно?
Например, если у меня есть такой код, time_tuple
будет ли он освобожден python?
PyObject* list = PyList_New(2);
PyObject *time_tuple = Py_BuildValue("(s, s)", "Time", "O");
PyList_SetItem(list, 0, time_tuple);
Py_XDECREF(time_tuple);
Py_XDECREF(list);
Пожалуйста, обратитесь к некоторой документации в вашем ответе, если можете.
Ответ №1:
Интерпретатор никогда не должен сталкиваться с отрицательным количеством ссылок. Если количество ссылок достигает нуля, это означает, что на этот объект нет ссылок. Объект будет освобожден, как только это произойдет.
Процитируем документацию по Python:
Если количество ссылок достигает нуля, вызывается функция освобождения типа объекта (которая не должна быть нулевой).
Смотрите также здесь для получения дополнительной информации.
Также важно отметить, что в Python, в дополнение к количеству ссылок, важно отслеживать, кому на самом деле принадлежат эти ссылки.
В приведенном вами примере:
-
Py_BuildValue()
возвращает новую ссылку, которая затем принадлежит вам и хранится вtime_tuple
. На этом этапе кортеж имеет количество ссылок, равное 1. -
PyList_SetItem()
крадет ссылку на владение, кортеж по-прежнему имеет количество ссылок, равное 1, но ссылка принадлежитlist
. -
Py_XDECREF(time_tuple)
уменьшает количество ссылок в кортеже до 0, и объект освобождается. Это ошибка, поскольку ссылка принадлежитlist
. -
Py_XDECREF(list)
уменьшает количество ссылок в списке до 0, и список освобождается. Ссылка на кортеж принадлежит списку, поэтому он уменьшает количество ссылок. -
К сожалению, кортеж уже выделен, и ваша программа завершается сбоем. Или, что еще хуже, это может продолжаться некоторое время, приводя к сбою в несвязанной части кода. Отладка этого обычно доставляет массу удовольствия.
Комментарии:
1. Я понимаю поведение владения ссылками на Python, вот почему я написал этот пример. Интересным фактом было то, что моя программа работала корректно без каких-либо сбоев, и я думал, что отрицательное количество ссылок обрабатывается как 0 ref count.