Fix list contents memory leak in wxAny unit test

Also document the need for using WX_CLEAR_LIST() when converting a
list-valued wxVariant to wxAny.

Note that we intentionally don't fix the problem by clearing the list
automatically, even if it could be done, because this would silently
break the existing code which does already clear the list -- and now
would attempt to clear it twice, with fatal consequences. Instead
document the existing behaviour and explain how to avoid memory leaks.
This commit is contained in:
Ilya Sinitsyn 2020-10-14 20:36:09 +07:00 committed by Vadim Zeitlin
parent 10c68e9973
commit f7c4677cb2
2 changed files with 21 additions and 0 deletions

View File

@ -84,6 +84,25 @@ public:
cannot be converted to a specific data type, wxAny will then cannot be converted to a specific data type, wxAny will then
hold and manage reference to wxVariantData* similar to how hold and manage reference to wxVariantData* similar to how
wxVariant does. wxVariant does.
Note that objects constructed from list-valued variants
require the list to be explicitly cleared using `WX_CLEAR_LIST`
to avoid leaking memory. This unfortunate behaviour will not
be changed to prevent breaking the existing code relying on it.
@code
wxVariant vList;
vList.NullList();
vList.Append(15);
vList.Append("abc");
// Create wxAny from the list variant.
wxAny any = wxAny(vList);
// Clear the list to avoid the memory leak.
wxAnyList anyList = any.As<wxAnyList>();
WX_CLEAR_LIST(wxAnyList, anyList);
@endcode
*/ */
wxAny(const wxVariant& variant); wxAny(const wxVariant& variant);

View File

@ -652,6 +652,8 @@ void wxAnyTestCase::wxVariantConversions()
CPPUNIT_ASSERT(variant.GetCount() == 2); CPPUNIT_ASSERT(variant.GetCount() == 2);
CPPUNIT_ASSERT(variant[0].GetLong() == 15); CPPUNIT_ASSERT(variant[0].GetLong() == 15);
CPPUNIT_ASSERT(variant[1].GetString() == "abc"); CPPUNIT_ASSERT(variant[1].GetString() == "abc");
// Avoid the memory leak.
WX_CLEAR_LIST(wxAnyList, anyList);
any = wxAny(vCustomType); any = wxAny(vCustomType);
CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxVariantData*)); CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxVariantData*));