Skip to content

Memory leak in the class is dynamically created in c++ library #1895

@Ilyasml

Description

@Ilyasml

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.

TheLeakReprodution.zip

Please, use x64 platform to run and build both projects. The initial discussion is also available by the link #1890

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions