Как интерпретатор python обрабатывает отрицательное количество ссылок на объект?

#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, в дополнение к количеству ссылок, важно отслеживать, кому на самом деле принадлежат эти ссылки.

В приведенном вами примере:

  1. Py_BuildValue() возвращает новую ссылку, которая затем принадлежит вам и хранится в time_tuple . На этом этапе кортеж имеет количество ссылок, равное 1.

  2. PyList_SetItem() крадет ссылку на владение, кортеж по-прежнему имеет количество ссылок, равное 1, но ссылка принадлежит list .

  3. Py_XDECREF(time_tuple) уменьшает количество ссылок в кортеже до 0, и объект освобождается. Это ошибка, поскольку ссылка принадлежит list .

  4. Py_XDECREF(list) уменьшает количество ссылок в списке до 0, и список освобождается. Ссылка на кортеж принадлежит списку, поэтому он уменьшает количество ссылок.

  5. К сожалению, кортеж уже выделен, и ваша программа завершается сбоем. Или, что еще хуже, это может продолжаться некоторое время, приводя к сбою в несвязанной части кода. Отладка этого обычно доставляет массу удовольствия.

Комментарии:

1. Я понимаю поведение владения ссылками на Python, вот почему я написал этот пример. Интересным фактом было то, что моя программа работала корректно без каких-либо сбоев, и я думал, что отрицательное количество ссылок обрабатывается как 0 ref count.