Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Ilyasml opened this issue Jan 24, 2025 · 0 comments
Open

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

Ilyasml opened this issue Jan 24, 2025 · 0 comments

Comments

@Ilyasml
Copy link

Ilyasml commented Jan 24, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant