Using C2Go
GC-aware allocation
Allocate typed C objects on the Go heap and preserve their pointer layout.Maintained byC2Go contributorsgc_malloc allocates zeroed memory on the Go heap. Unlike ordinary C allocation, it accepts runtime type information so the collector knows which machine words contain pointers.
Allocate one record
#include <c2go.h>
#include <stddef.h>
#include <stdint.h>
struct managed Node {
struct Node *next;
int value;
};
struct Node *new_node(int value) {
struct Node *node = gc_malloc(
c2go_typeinfo(struct Node),
sizeof(struct Node)
);
if (node == NULL) {
return NULL;
}
node->value = value;
return node;
}
c2go_typeinfo(struct Node) is a compiler builtin exposed as a macro. It produces the Go runtime type descriptor for that named managed record. You do not write or register the pointer bitmap by hand.
There is no matching free: the Go GC reclaims the object after it becomes unreachable.
Heap allocation is also the required rewrite when a value must outlive its C stack frame. Never store &local in this object; C2Go does not automatically move that local to the heap. See Stack escape safety.
Allocate an array
Use gc_malloc_array when pointer metadata must repeat for every element:
struct Node *nodes = gc_malloc_array(
c2go_typeinfo(struct Node),
sizeof(struct Node),
count
);
The runtime repeats the element pointer bitmap across the allocation, analogous to allocating a Go slice backing array.
The current inline helper directly computes elem_size * count; it does not check multiplication overflow for the caller. For untrusted lengths, first validate count <= SIZE_MAX / elem_size and check the returned pointer for NULL.
Allocate a pointer-free blob
Passing NULL as type information creates memory that the GC does not scan for pointers:
unsigned char *bytes = gc_malloc(NULL, byte_count);
Only do this when the allocation will never contain managed pointers. Hiding a managed pointer inside a blob can let the referenced object become unreachable from the GC’s point of view.
Do not mix ownership models
| Allocator | World | Release |
|---|---|---|
gc_malloc / gc_malloc_array |
typed managed Go heap | automatic GC |
malloc / calloc / realloc |
c2go-libc unmanaged C-semantics storage | free |
Never call free on a typed Go-heap pointer, and do not assume a native library can retain a managed pointer indefinitely. If a native API takes ownership, use the allocator that API explicitly requires and copy the data, or design a stable handle boundary. c2go-libc’s malloc is not the host system malloc.
Type information constraints
c2go_typeinfo requires a named, complete record type. Anonymous records and reserved runtime identifiers are rejected. Packed or custom-aligned managed records produce warnings and target-specific generated layouts; prefer natural layout for portable public types.
Next, scale the same rules across multi-file projects and LTO.