项目作者: AlxHnr

项目描述 :
Region-based memory management library
高级语言: C
项目地址: git://github.com/AlxHnr/CRegion.git
创建时间: 2019-06-30T10:04:25Z
项目社区:https://github.com/AlxHnr/CRegion

开源协议:Creative Commons Zero v1.0 Universal

下载


travis
codecov
license

A free, public-domain
region
implementation without any dependencies. It conforms strictly to C99 and is
valgrind-clean. Allocation failures and arithmetic overflows are handled by
calling exit().

Copy the files from src/ into your project and add them to your build
script.

Examples

  1. #include "region.h"
  2. CR_Region *r = CR_RegionNew();
  3. char *data = CR_RegionAlloc(r, 1024);
  4. CR_RegionRelease(r); /* If omitted, it will be released trough atexit() */

Callbacks can be attached to regions and will be called when the region
gets released:

  1. void cleanup(void *data) { /* ... */ }
  2. Foo *foo = createFoo();
  3. CR_RegionAttach(r, cleanup, foo);

Memory allocated via CR_RegionAlloc() has a fixed size and can not be
reallocated. Use CR_RegionAllocGrowable() to get growable memory:

  1. #include "alloc-growable.h"
  2. char *buffer = CR_RegionAllocGrowable(r, 24);
  3. /* Grow the buffer if needed. */
  4. buffer = CR_EnsureCapacity(buffer, 128);

In the example above the lifetime of buffer will be bound to the region
r. If r gets released, buffer will also be released. To bind a buffer
to the lifetime of the entire program, initialize it to NULL:

  1. static char *buffer = NULL;
  2. buffer = CR_EnsureCapacity(buffer, 128);

Objects with a very short lifetime can be allocated using a memory pool,
which allows reusing memory in a region:

  1. #include "mempool.h"
  2. CR_Mempool *int_pool = CR_MempoolNew(r, sizeof(int), NULL, NULL);
  3. int *value = CR_MempoolAlloc(int_pool);
  4. *value = -12;

The lifetime of memory returned from the pool is bound to pool itself,
which in turn is bound to the region. Objects can be released manually:

  1. CR_DestroyObject(value);

Objects allocated by the pool can have destructors. To do so, two callbacks
can to be provided to the mempool.

The first one will be called when destroying objects explicitly by using
CR_DestroyObject(). This callback is allowed to handle errors by calling
exit().

The second callback will be called for objects that have not been destroyed
explicitly. It will be invoked when the mempool gets released together with
its associated region. This callback is not allowed to call exit(),
because it may be called while the program is terminating.

The mempool guarantees that only one of these callbacks will be called
for the same object.

  1. /* This destructor will be called when an object is passed to
  2. CR_DestroyObject(). */
  3. int closeFile(void *data)
  4. {
  5. FileHandle *file = data;
  6. if(syncToDiskAndClose(file) == ERROR)
  7. {
  8. CR_ExitFailure("failed to write important file");
  9. }
  10. /* This function returns an int, to have a signature different from the
  11. other destructor. The returned value will be ignored. */
  12. return 0;
  13. }
  14. /* This will be called for objects which couldn't be destroyed explicitly
  15. (e.g. the program called exit() prematurely). It is not allowed to call
  16. exit() and will be invoked when the mempool (and its owning region) get
  17. released. */
  18. void freeFile(void *data)
  19. {
  20. FileHandle *file = data;
  21. (void)syncToDiskAndClose(file);
  22. }
  23. CR_Mempool *file_pool = CR_MempoolNew(r, sizeof(FileHandle), closeFile, freeFile);
  24. FileHandle *file = CR_MempoolAlloc(file_pool);
  25. file->stream = openStream("/dev/null");
  26. CR_EnableObjectDestructor(file); /* Must be done explicitly after the
  27. object is fully constructed */

Debugging and sanitizing

This library allocates mostly from continuous memory, which makes it
impossible for debugging tools to detect overflows. In order to use such
tools, continuous memory has to be disabled. This can be achieved by
defining CREGION_ALWAYS_FRESH_MALLOC during compilation. Doing so causes
CRegion to return new, fresh memory from raw malloc on every single
allocation.

Caveats

Runtime leak-detectors are not useful because CRegion will clean up
everything when the program terminates. Changing this behaviour would
require invasive modifications to the library and to code using this
library. This would break the way CRegion is intended to be used. CRegion
is not thread-safe.