mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 14:32:43 +00:00
64 lines
3.1 KiB
Markdown
64 lines
3.1 KiB
Markdown
Memory allocation and ownership
|
|
-------------------------------
|
|
|
|
Any library needs to _take_ data from users, and then _return_ data to
|
|
users. With some types this is simple - integer parameters and return
|
|
types are trivial. But with more complex data types, things are more
|
|
complicated. Even something seemingly simple, like a C string, requires
|
|
discipline: we cannot simple return an allocated hunk of memory for
|
|
callers to `free`, since some systems have multiple allocators and users
|
|
cannot necessarily reason about the allocator used and which corresponding
|
|
deallocation function to call to free the memory.
|
|
|
|
## Objects
|
|
|
|
Most types in libgit2 are "opaque" types, which we treat as "objects" (even
|
|
though C is "not an object oriented language"). You may create an object -
|
|
for example, with `git_odb_new`, or libgit2 may return you an object as an
|
|
"out" parameter - for example, with `git_repository_open`. With any of
|
|
these objects, you should call their corresponding `_free` function (for
|
|
example, `git_odb_free` or `git_repository_free`) when you are done using
|
|
them.
|
|
|
|
## Structures
|
|
|
|
libgit2 will often take _input_ as structures (for example, options
|
|
structures like `git_merge_options`). Rarely, libgit2 will return data in
|
|
a structure. This is typically used for simpler data types, like `git_buf`
|
|
and `git_strarray`. Users should allocate the structure themselves (either
|
|
on the stack or the heap) and pass a pointer to it. Since libgit2 does not
|
|
allocate the structure itself, only the data inside of it, the deallocation
|
|
functions are suffixed with `_dispose` instead of `_free`, since they only
|
|
free the data _inside_ the structure.
|
|
|
|
## Strings or continuous memory buffers (`git_buf`)
|
|
|
|
libgit2 typically _takes_ NUL-terminated strings ("C strings") with a
|
|
`const char *`, and typically _takes_ raw data with a `const char *` and a
|
|
corresponding `size_t` for its size. libgit2 typically _returns_ strings
|
|
or raw data in a `git_buf` structure. The given data buffer will always be
|
|
NUL terminated (even if it contains binary data) and the `size` member will
|
|
always contain the size (in bytes) of the contents of the pointer (excluding
|
|
the NUL terminator).
|
|
|
|
In other words, if a `git_buf` contains the string `foo` then the memory
|
|
buffer will be { `f`, `o`, `o`, `\0` } and the size will be `3`.
|
|
|
|
Callers _must_ initialize the buffer with `GIT_BUF_INIT` (or by setting
|
|
all the members to `0`) when it is created, before passing a pointer
|
|
to the buffer to libgit2 for the first time.
|
|
|
|
Subsequent calls to libgit2 APIs that take a buffer can re-use a
|
|
buffer that was previously used. The buffer will be cleared and grown
|
|
to accommodate the new contents (if necessary). The new data will
|
|
written into the buffer, overwriting the previous contents. This
|
|
allows callers to reduce the number of allocations performed by the
|
|
library.
|
|
|
|
Callers must call `git_buf_dispose` when they have finished.
|
|
|
|
Note that the deprecated `git_diff_format_email` API does not follow
|
|
this behavior; subsequent calls will concatenate data to the buffer
|
|
instead of rewriting it. Users should move to the new `git_email`
|
|
APIs that follow the `git_buf` standards.
|