Freeing memory of a cgo library

388 views
Skip to first unread message

Liron Levy

unread,
May 24, 2018, 8:35:07 AM5/24/18
to golang-nuts
Hey guys,

I'm in a bit of a mass, I can not see how I'm getting out of...
What do I got:
* A library I built using cgo.
* A cpp app using this library (dll).

What do I do:
I try to free memory I have allocated in the cgo library in the cpp app.

What Tools do I use:
To build the library (dll) I use cgo, then creating a stub lib using the VS cmd. 
I use visual studio 2017 to compile the app (with /MD) option.

What do I get:
Critical error detected c0000374

As far as I can see, this is a result of me freeing data which was allocated in the dll libarary.
I will note that this does not happen if I create a test app and compile it with gcc.

Unfortunately, I can not avoid using VS as I am working with some CUDA stuff which like VS better :/

Thanks for taking the time to read\help,
Liron
 

jake...@gmail.com

unread,
May 25, 2018, 12:04:45 PM5/25/18
to golang-nuts
Looks like you are on windows. I have worked a lot with windows, C/C++ and go, but never actually built a go dll. But, since no one else has picked this up, maybe I can help.

1. I'm not sure what "the cgo" library means here? Do you have this: cpp<->go(dll)<->c(cgo)? Or something else.

2. How is the memory in question allocated? What is the line of code that allocates it, and where does it reside in the chain above?

Liron Levy

unread,
May 25, 2018, 12:47:58 PM5/25/18
to golang-nuts
Hey Jake,

First if all thanks for the willing to help.

Cgo is the built-in tool in go of building c libraries (see: https://golang.org/cmd/cgo/)

What I basically do is that I have a go code, which i build into c library (dll), i.e, i insert the go code onto the cgo mechine then get .h and .dll on the otherside.

The memory is allocated inside the .dll using C.malloc (which is basically c malloc), and i try to free it inside the cpp file which is linked to this dll.

If i build a function inside the go code to free a recived pointer, which will end up in the dll, then the problem is avoided.

That being said, due to the fact that I have quite a few callbacks and a large data transfer between the dll and my app i would like to keep it simple and not have to use a third function to free the mallocs, as it is also a problem if it happens the other way around, i.e., if i allocate memory in the app and try to free it inside the library.

Sorry if im unclear i tried to explsin it the best as i can.

Ps yes i do use windiws, a side remark is that if i use gcc this does not happen.

alex....@gmail.com

unread,
May 25, 2018, 1:58:52 PM5/25/18
to golang-nuts
Memory allocated by one C/C++ runtime must and can only be freed through the same runtime. This is not a Go/cgo problem, this is normal C/C++ behavior.
So by mixing gcc and msvc there are at least 2 C/C++ runtimes. Even mixing different compiler versions might cause issues.

Liron Levy

unread,
May 25, 2018, 2:15:32 PM5/25/18
to golang-nuts
Well it is kinda reoated as im in this mass because of go :)

Anyway, is there anyway to use cgo with msvc? I actually run the cgo command from msvc cmd assuming the c part will be compiled with msvc.

In addition as far as i know you can actually do that with visual studio if you put the /md (multi threading) flag on.

alex....@gmail.com

unread,
May 25, 2018, 2:26:03 PM5/25/18
to golang-nuts
Nope, not ATM. Go only works with gcc, even the dlls are made with gcc.
There is a issue on that and it seems like there is some progress but it isn't clear when it will be usable. https://github.com/golang/go/issues/20982

Also note that even if Go uses msvc, you would still have issues freeing memory allocated in the dll through the exe unless maybe both of them are not static linking the runtime and are using the exact same runtime.
You can see this for some info on the topic https://blogs.msdn.microsoft.com/oldnewthing/20060915-04/?p=29723

Liron Levy

unread,
May 25, 2018, 2:35:19 PM5/25/18
to golang-nuts
Gotcha :)

Thanks for the info, guess i will have to find a way around it then. At least i now know there is no real way to do what i wanted so that close this door :)

jake...@gmail.com

unread,
May 26, 2018, 12:14:42 PM5/26/18
to golang-nuts
FYI, the standard way around this is to expose a "free" method from your DLL for memory allocated by the DLL. The other way is to require that users of the DLL supply the memory in advance to functions needing it. These two methods are the ones used by the Windows libraries themselves. Pretty standard stuff. One other possibility might be to register some sort of callback from the C++ code that the go DLL code can call to allocate memory from the C++ space. But I would not prefer that.

Good Luck.

Liron Levy

unread,
May 26, 2018, 2:19:55 PM5/26/18
to golang-nuts
Hey Jake,

Yes, i will probably go with the first option :) feel a bit massy but it is probably the better way to go... Plus in my case probably the only way hahaha.

Thanks a lot for helping.

Reply all
Reply to author
Forward
0 new messages