Memory management of pure C libraries

Hi I’m relatively new to both C++ and Unreal. Despite that I’m trying some crazy things and I’m currently hacking on my editor plugin which integrates a third party library written in pure C (libgit2).

Albeit slowly, I’m starting to make some progress. The thing I’m struggling a bit with is managing memory of objects allocated by the third party C library that needs calling specific cleanup functions. The cleanest approach seems to be to wrap the library’s functionality in proper C++ RAII wrappers, but I wondered if I could avoid that as it seems a bit of an overkill for what I’ll use from the library and existing wrappers seem either a bit outdated or introduce unwanted dependencies.

A nice compromise seems to use smart pointers with custom deleters, but Unreal’s TSharedPtr doesn’t support them (correct me if I’m wrong). It works well for me with stdlib’s smart pointers like explained here , but I see around the web that stdlib should be avoided in Unreal. Maybe it doesn’t matter much when it comes to editor-only plugins and I can safely reference it, or could it be problematic if maybe in the future I’d want to publish the plugin to the marketplace. Note that I would only use these in the internals of the plugin.

Thanks.

What does the code looks like ? Does in uses “new” and “delete” expressions or malloc and free to allocate memory ?

Btw the shared pointer is basically the same as unique pointer however the difference is that shared pointer instead of coping it self when new instance is requested it will increase the reference counter and reference the same block of memory and when you delete it it will decrease reference counter but if it references something else the memory will not be freed unless you do manually, if no references left memory will be freed, unreal supports unique pointers look here

Can you confirm that it leaks ? for example try to open wrong repository and test the returned pointer value I think if it fails the memory is not allocated and pointer gets null-ed what are the repository_open() look like internally ?

e leak mean if you allocate memory and forget to free it so if for some reason the git lib will throw the memory will not be allocated and the pointer is null-ed
pointer only stores memory address when pointer points to invalid address it is called a “dangling” pointer can you send me a link to the source code of library you using

The C library allocates and frees inside its functions. Just an example:

const char* WorkingCopyDir = "/home/cician/Workspace/Unreal/test_projects/GItSAWTestRepo1";
git_repository* RawRepo = nullptr;
if (!git_repository_open(&RawRepo, WorkingCopyDir))
	return nullptr;
git_repository_free(RawRepo);

The above snippet of course leaks in case of error returned from git_repository_open. The whole point is how to cleanly handle deallocations which becomes ugly quickly without RAII or smart pointers because RawRepo is just one of tens of objects to manage.

edit: grammar

It obviously leaks since RawRepo is a pure C pointer. The docs specifically say to call git_repository_free and the rest of the library uses the same pattern. I’m trying to find a simple yet correct way to manage these objects from c++. If everything else fails I’ll do RAII wrappers like a good C++ citizen.

https://libgit2.github.com/libgit2/#HEAD/group/repository/git_repository_open
https://github.com/libgit2/libgit2/blob/master/src/repository.c#L549

Yeah, TUniquePtr will probably suffice since almost whole code calling into the C library may end up being one big function and no state needs to be kept by the library.

Though the point is that Unreal’s Smart Pointer classes don’t support custom deleters according to the documentation so I can’t use them to manage the C pointers that should be freed with libraries functions instead of just delete.

OK I see the point now. Yep it will probably free the repo object in case of error on open. So this wasn’t exactly a good example.
In the real code I’m doing other things between git_repository_open and git_repository_free that can break and I want to exit the function clean the repo and other objects.

Sure, that is first thing I tried. The code becomes pretty ugly relatively soon though. Now I have 4 objects to deallocate. And I’m barely starting the initialization phase.
I need to keep some kind of “ok” guard variable and test it repeatedly or use a goto with a CLEANUP label (goto, bleeah). Or should I maybe enable exceptions and cleanup in catch?

const char* WorkingCopyDir = “/home/cician/Workspace/Unreal/test_projects/GItSAWTestRepo1”;
git_repository* RawRepo = nullptr;
if (!git_repository_open(&RawRepo, WorkingCopyDir))
return nullptr;
git_repository_free(RawRepo); // this will not be executed when open fails due to return statement abowe

I’m telling you there will be no leak when open fails there will be a leak when it succeed and for some reason you forget to git_repository_free(RawRepo); after you done using it

than you can just use a conditional statements

if (whateverDone == false)
{
CleanUp;
}

Unless you want to use TUniquePtr than it will be freed automatically as soon as it goes out of scope

use smart pointers than

Hi,

FYI, TSharedPtr does support custom deleters. You can do something like this, for example:

TSharedPtr<T*> MyPtr = MakeShareable(ThirdPartyAllocateT(), [](T* Ptr){ ThirdPartyDeallocateT(Ptr); });

Steve

Worked like a charm, thanks!

Actually I found the overload earlier, but I tried it and it didn’t work with my first attempt so I assumed it was some work in progress or something since the docs say explicitly that custom deleters are not supported. Must’ve been some basic mistake on my part.

Looks like an old doc - I’ll get it updated, thanks!

Steve