mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
smart pointer refcount fix by @dean0x7d with slight modifications (fixes #471)
This commit is contained in:
parent
0a9ef9c300
commit
bd560acf40
@ -1134,6 +1134,7 @@ private:
|
|||||||
} catch (const std::bad_weak_ptr &) {
|
} catch (const std::bad_weak_ptr &) {
|
||||||
new (&inst->holder) holder_type(inst->value);
|
new (&inst->holder) holder_type(inst->value);
|
||||||
}
|
}
|
||||||
|
inst->owned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize holder object, variant 2: try to construct from existing holder object, if possible
|
/// Initialize holder object, variant 2: try to construct from existing holder object, if possible
|
||||||
@ -1144,6 +1145,7 @@ private:
|
|||||||
new (&inst->holder) holder_type(*holder_ptr);
|
new (&inst->holder) holder_type(*holder_ptr);
|
||||||
else
|
else
|
||||||
new (&inst->holder) holder_type(inst->value);
|
new (&inst->holder) holder_type(inst->value);
|
||||||
|
inst->owned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize holder object, variant 3: holder is not copy constructible (e.g. unique_ptr), always initialize from raw pointer
|
/// Initialize holder object, variant 3: holder is not copy constructible (e.g. unique_ptr), always initialize from raw pointer
|
||||||
|
@ -290,7 +290,28 @@ void init_issues(py::module &m) {
|
|||||||
for (auto &e : nothrows) l.append(py::cast(e));
|
for (auto &e : nothrows) l.append(py::cast(e));
|
||||||
return l;
|
return l;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
/// Issue #471: shared pointer instance not dellocated
|
||||||
|
class SharedChild : public std::enable_shared_from_this<SharedChild> {
|
||||||
|
public:
|
||||||
|
SharedChild() { print_created(this); }
|
||||||
|
~SharedChild() { print_destroyed(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedParent {
|
||||||
|
public:
|
||||||
|
SharedParent() : child(std::make_shared<SharedChild>()) { }
|
||||||
|
const SharedChild &get_child() const { return *child; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<SharedChild> child;
|
||||||
|
};
|
||||||
|
|
||||||
|
py::class_<SharedChild, std::shared_ptr<SharedChild>>(m, "SharedChild");
|
||||||
|
py::class_<SharedParent, std::shared_ptr<SharedParent>>(m, "SharedParent")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def("get_child", &SharedParent::get_child, py::return_value_policy::reference);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// MSVC workaround: trying to use a lambda here crashes MSCV
|
// MSVC workaround: trying to use a lambda here crashes MSCV
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import gc
|
import gc
|
||||||
|
from pybind11_tests import ConstructorStats
|
||||||
|
|
||||||
|
|
||||||
def test_regressions():
|
def test_regressions():
|
||||||
@ -187,3 +188,16 @@ def test_dupe_assignment():
|
|||||||
""" Issue 461: overwriting a class with a function """
|
""" Issue 461: overwriting a class with a function """
|
||||||
from pybind11_tests.issues import dupe_exception_failures
|
from pybind11_tests.issues import dupe_exception_failures
|
||||||
assert dupe_exception_failures() == []
|
assert dupe_exception_failures() == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_enable_shared_from_this_with_reference_rvp():
|
||||||
|
""" Issue #471: shared pointer instance not dellocated """
|
||||||
|
from pybind11_tests import SharedParent, SharedChild
|
||||||
|
|
||||||
|
parent = SharedParent()
|
||||||
|
child = parent.get_child()
|
||||||
|
|
||||||
|
cstats = ConstructorStats.get(SharedChild)
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del child, parent
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
Loading…
Reference in New Issue
Block a user