Skip to content

Using py::keep_alive<N, P>() may cause internals.patients[nurse] to grow without bounds #1251

@EricCousineau-TRI

Description

@EricCousineau-TRI

Looking at some of the internals, it looks like return_value_policy::reference_internal is only "activated" when an instance is created newly registered:
https://github.com/pybind/pybind11/blob/48e1f9a/include/pybind11/cast.h#L552

However, py::keep_alive<N, P>() looks like it is always activated:
https://github.com/pybind/pybind11/blob/48e1f9a/include/pybind11/pybind11.h#L140
https://github.com/pybind/pybind11/blob/48e1f9a/include/pybind11/attr.h#L442
https://github.com/pybind/pybind11/blob/48e1f9a/include/pybind11/pybind11.h#L1470
https://github.com/pybind/pybind11/blob/48e1f9a/include/pybind11/detail/class.h#L289

A simple fix (for only pybind-registered objects) would be to add a simple check:

#include <algorithm>
...
auto& p = internals.patients[nurse];
if (std::find(p.begin(), p.end(), patient) != p.end()) ...

This would impact performance a little, but would prevent a packrat problem for long(er)-running Python programs.

Not sure about the non-pybind case in keep_alive_impl; however, it looks like this would just leak some reference counting, which may be less of an issue than an array growing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions