-
Notifications
You must be signed in to change notification settings - Fork 530
Open
Description
Suppose there is a c++ class structure, listed below
class IBaseInterface
{
public:
virtual int Type()
{
return 0;
}
IBaseInterface()
{
}
virtual ~IBaseInterface()
{
}
};
class IString :public IBaseInterface
{
public:
virtual const wchar_t* String()
{
return nullptr;
}
virtual HRESULT SetStringOutProp(const wchar_t* Value)
{
return 0;
}
IString() = default;
virtual ~IString() = default;
};
class RealStringClass: public IString
{
public:
virtual ~RealStringClass()
{
int i = 0;
i++;
}
std::wstring m_String;
virtual const wchar_t* String() override;
virtual HRESULT SetStringOutProp(const wchar_t* Value) override;
virtual int Type() override
{
return 1;
}
};
There are two functions which are used to delete and create the object, implementing the interface:
IString* CreateString()
{
RealStringClass* ret = new RealStringClass();
return ret;
}
void DeleteInterface(IBaseInterface* ToDelete)
{
delete (IBaseInterface*)ToDelete;
}
All works well, except the fact that each call of the create/destroy functions for the IString interface leads to a memory leak:
IString stringNative = CppLibraryInterfaceDesk.CreateString();
CppLibraryInterfaceDesk.DeleteInterface(stringNative);
The leak looks like
Detected memory leaks!
Dumping objects ->
{222} normal block at 0x00000232E02AB650, 48 bytes long.
Data: < > C8 12 9A BE FE 7F 00 00 00 00 00 00 00 00 00 00
{220} normal block at 0x00000232E02AD2C0, 48 bytes long.
Data: < > C8 12 9A BE FE 7F 00 00 00 00 00 00 00 00 00 00
{218} normal block at 0x00000232E02AD250, 48 bytes long.
Data: < > C8 12 9A BE FE 7F 00 00 00 00 00 00 00 00 00 00
{216} normal block at 0x00000232E02AB730, 48 bytes long.
Data: < > C8 12 9A BE FE 7F 00 00 00 00 00 00 00 00 00 00
{214} normal block at 0x00000232E02AB5E0, 48 bytes long.
Data: < > C8 12 9A BE FE 7F 00 00 00 00 00 00 00 00 00 00
The most probable reason for a leak is that memory allocated for the object itself has not been deleted, because if the create and destroy functions are rewritten as below, then there is no leak
IString* CreateString()
{
byte* mem = new byte[sizeof(RealStringClass)];
RealStringClass *ret = new(mem) RealStringClass();
return ret;
}
void DeleteInterface(IBaseInterface* ToDelete)
{
delete (IBaseInterface *)ToDelete;
delete[](byte*)ToDelete;
}
Please, refer to the projects in the arhive, the DO_LEAK
flag in cppLibraryRealClass.cpp can be used to reproduce the issue.
Please, use x64 platform to run and build both projects. The initial discussion is also available by the link #1890
Metadata
Metadata
Assignees
Labels
No labels