Open
Description
gsl::owner<int*> Owner1 = new int(42);
gsl::owner<int*> Owner2 = Owner1;
// Owner1 = nullptr;
This may lead to double free because following the core guidelines rules we must call delete Owner1;
and delete Owner2;
later.
Another interesting double owning case is regarding move constructors and move assignments:
class Foo {
gsl::owner<int*> ptr=nullptr;
public:
~Foo() {
delete ptr;
}
Foo(Foo&& r) : ptr(r.ptr) {
// r.ptr = nullptr;
}
Foo& operator=(Foo&& r) {
if (&r != this) {
ptr = r.ptr;
// r.ptr = nullptr;
}
return *this;
}
};
In practice, such kind of wrong code mostly reached due to the fact that people expect std::move
to set it's pointer argument to nullptr
but it never do that:
Foo(Foo&& r) : ptr(std::move(r.ptr)) { // BAD
}
Foo& operator=(Foo&& r) {
if (&r != this) {
ptr = std::move(r.ptr); // BAD
}
return *this;
}