mocha-engine / mocha

Mocha: A work-in-progress 3D game engine
GNU Lesser General Public License v3.0
53 stars 7 forks source link

Possible interop memory leak when passing temporary strings from native to managed #43

Open MuffinTastic opened 1 year ago

MuffinTastic commented 1 year ago

In Host engine.h, a new C string is allocated like so:

GENERATE_BINDINGS inline const char* GetProjectPath()
{
    std::string str = EngineProperties::LoadedProject.GetValue();

    // Copy string so we can use it out-of-scope
    char* cstr = new char[str.length() + 1];
    strcpy_s( cstr, str.length() + 1, str.c_str() );

    return cstr;
};

In the generated interop code on the managed side it's then converted to a C# string by use of MemoryContext:

public static string GetProjectPath(  ) 
{
    using var ctx = new MemoryContext( "Engine.GetProjectPath" );
    return ctx.GetString( _GetProjectPath(  ) );
}

MemoryContext.GetString() is defined as such:

internal string GetString( IntPtr strPtr )
{
    return Marshal.PtrToStringUTF8( strPtr ) ?? "UNKNOWN";
}

Marshal.PtrToStringUTF8()'s description says:

Allocates a managed String and copies all characters up to the first null character from an unmanaged UTF-8 string into it.

I don't see where cstr gets deallocated in this chain.