Ownership

4 Posts

C Strings, Memory Ownership, and Error Returns

7 minute

In FFI, extern "C" is only the entry point.

The most fragile parts are usually:

whether a C string is a valid NUL-terminated string
who allocates returned pointers, who frees them, and which function frees them
whether errors cross the boundary as integer codes, output parameters, or text

C code handles these through API documentation and discipline. Rust can put some rules into types, but the language boundary still needs an explicit contract.

Read More

Library API Design, First Layer

5 minute

In C library APIs, one pointer can mean many different things:

int parse_packet(const uint8_t *data, size_t len, struct Packet *out);
void normalize(uint8_t *data, size_t len);
void consume_buffer(uint8_t *data, size_t len);
uint8_t *make_packet(size_t *out_len);

These signatures all involve pointers, but the API meaning differs:

  • read-only input
  • in-place mutation
  • output result
  • taking over a caller-owned resource
  • creating a new resource for the caller

The first layer of Rust API design is making those intentions visible in the type.

Read-Only Input: Borrow

C read-only buffer:

uint32_t checksum(const uint8_t *data, size_t len);

Rust uses a slice:

fn checksum(data: &[u8]) -> u32 {
    data.iter().map(|b| *b as u32).sum()
}

&[u8] means the function temporarily reads bytes. It does not own the memory and cannot mutate it.

Read More

Ownership: Who Owns, Who Frees

5 minute

C code already has ownership.

Whenever memory needs free, a file needs fclose, or a handle needs release, there is a question: who is responsible for releasing it?

C’s problem is not the absence of ownership. The problem is that ownership is usually not in the type. It lives in function names, comments, conventions, and team experience. Rust ownership turns those conventions into rules the compiler can check.

This article covers one core question: who owns, who frees, and why a moved value cannot be used again.

Read More

Resource Cleanup: From cleanup to Drop

5 minute

In C, resource cleanup is maintained by people.

Open a file and you need fclose. Allocate memory and you need free. Take a lock and you need to unlock it. Initialize an object and every error path must destroy it. Once a function has several resources, goto cleanup becomes the common structure.

Rust does not remove cleanup. It binds cleanup responsibility to whoever owns the resource. When a value leaves scope, its cleanup logic runs automatically. This mechanism is Drop.

Read More