3

I have a package that interfaces with a C library. Now I need to store a pointer to a C struct in the Go struct

type A struct {
  s *C.struct_b
}

Obviously this pointer needs to be freed before the struct is collected by the GC. How can I accomplish that?

1 Answers1

5

The best thing to do is when possible copy the C struct into go controlled memory.

var ns C.struct_b
ns = *A.s
A.s = &ns

Obviously, that won't work in all cases. C.struct_b may be too complicated or shared with something still in C code. In this case, you need to create a .Free() or .Close() method (whichever makes more sense) and document that the user of your struct must call it. In Go, a Free method should always be safe to call. For example, after free is run, be sure to set A.s = nil so that if the user calls Free twice, the program does not crash.

There is also a way to create finalizers. See another answer I wrote here. However, they may not always run and if garbage is created fast enough, it is very possible that the creation of garbage will out pace collection. This should be considered as a supplement to having a Free/Close method and not a replacement.

Community
  • 1
  • 1
Stephen Weinberg
  • 51,320
  • 14
  • 134
  • 113
  • No, just very few instances are created. I think I'll go with the finalizer approach, because the struct is opaque (imported from a library) and I don't know how complex it is. –  Feb 01 '13 at 18:33
  • I recommend you provide a .Free() method and if possible use it. As I said, finalizers are a backup, they should not be the only thing you rely on. – Stephen Weinberg Feb 01 '13 at 19:10
  • Yep, that's how I did it. I have a `Destroy()` method and use the finalizer as a backup. –  Feb 01 '13 at 19:34