Fixed memory leak when a Value contained heap-allocated data (Matrix, Vector, etc) - incorrect syntax when calling destructor did not do a virtual call so derived Value object was not cleaned up.
parent
fac426c5ac
commit
4a57ef65d7
|
|
@ -47,8 +47,8 @@ public:
|
||||||
* Destroy and deallocate this object, only if it was originally allocated using clone_().
|
* Destroy and deallocate this object, only if it was originally allocated using clone_().
|
||||||
*/
|
*/
|
||||||
virtual void deallocate_() const {
|
virtual void deallocate_() const {
|
||||||
this->Value::~Value();
|
this->~DerivedValue(); // Virtual destructor cleans up the derived object
|
||||||
boost::singleton_pool<PoolTag, sizeof(DERIVED)>::free((void*)this);
|
boost::singleton_pool<PoolTag, sizeof(DERIVED)>::free((void*)this); // Release memory from pool
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,27 @@ using symbol_shorthand::L;
|
||||||
|
|
||||||
const Symbol key1('v',1), key2('v',2), key3('v',3), key4('v',4);
|
const Symbol key1('v',1), key2('v',2), key3('v',3), key4('v',4);
|
||||||
|
|
||||||
|
|
||||||
|
class TestValueData {
|
||||||
|
public:
|
||||||
|
static int ConstructorCount;
|
||||||
|
static int DestructorCount;
|
||||||
|
TestValueData(const TestValueData& other) { cout << "Copy constructor" << endl; ++ ConstructorCount; }
|
||||||
|
TestValueData() { cout << "Default constructor" << endl; ++ ConstructorCount; }
|
||||||
|
~TestValueData() { cout << "Destructor" << endl; ++ DestructorCount; }
|
||||||
|
};
|
||||||
|
int TestValueData::ConstructorCount = 0;
|
||||||
|
int TestValueData::DestructorCount = 0;
|
||||||
|
class TestValue : public DerivedValue<TestValue> {
|
||||||
|
TestValueData data_;
|
||||||
|
public:
|
||||||
|
virtual void print(const std::string& str = "") const {}
|
||||||
|
bool equals(const TestValue& other, double tol = 1e-9) const { return true; }
|
||||||
|
virtual size_t dim() const { return 0; }
|
||||||
|
TestValue retract(const Vector&) const { return TestValue(); }
|
||||||
|
Vector localCoordinates(const TestValue&) const { return Vector(); }
|
||||||
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST( Values, equals1 )
|
TEST( Values, equals1 )
|
||||||
{
|
{
|
||||||
|
|
@ -358,6 +379,26 @@ TEST(Values, Symbol_filter) {
|
||||||
LONGS_EQUAL(2, i);
|
LONGS_EQUAL(2, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(Values, Destructors) {
|
||||||
|
// Check that Value destructors are called when Values container is deleted
|
||||||
|
{
|
||||||
|
Values values;
|
||||||
|
{
|
||||||
|
TestValue value1;
|
||||||
|
TestValue value2;
|
||||||
|
LONGS_EQUAL(2, TestValueData::ConstructorCount);
|
||||||
|
LONGS_EQUAL(0, TestValueData::DestructorCount);
|
||||||
|
values.insert(0, value1);
|
||||||
|
values.insert(1, value2);
|
||||||
|
}
|
||||||
|
LONGS_EQUAL(4, TestValueData::ConstructorCount);
|
||||||
|
LONGS_EQUAL(2, TestValueData::DestructorCount);
|
||||||
|
}
|
||||||
|
LONGS_EQUAL(4, TestValueData::ConstructorCount);
|
||||||
|
LONGS_EQUAL(4, TestValueData::DestructorCount);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue