#include <stddef.h>
#include <stdio.h>
#include "cbl/except.h"
Data Structures | |
struct | mem_loginfo_t |
contains the information about invalid memory operations. More... | |
Defines | |
#define | MEM_ALLOC(n) (mem_alloc((n), __FILE__, __LINE__)) |
allocates storage of the size n in bytes. | |
#define | MEM_CALLOC(c, n) (mem_calloc((c), (n), __FILE__, __LINE__)) |
allocation zero-filled storage of the size c * n in bytes. | |
#define | MEM_NEW(p) ((p) = MEM_ALLOC(sizeof *(p))) |
allocates to p storage whose size is determined by the size of the pointed-to type by p . | |
#define | MEM_NEW0(p) ((p) = MEM_CALLOC(1, sizeof *(p))) |
allocates to p zero-filled storage whose size is determined by the size of the pointed-to type by p . | |
#define | MEM_FREE(p) ((void)(mem_free((p), __FILE__, __LINE__), (p)=0)) |
deallocates storage pointed to by p and set it to a null pointer. | |
#define | MEM_RESIZE(p, n) ((p) = mem_resize((p), (n), __FILE__, __LINE__)) |
adjusts the size of storage pointed to by p to n bytes. | |
Functions | |
memory allocating functions: | |
void * | mem_alloc (size_t, const char *, int) |
allocates storage of the size n in bytes. | |
void * | mem_calloc (size_t, size_t, const char *, int) |
allocates zero-filled storage of the size c * n in bytes. | |
memory deallocating functions: | |
void | mem_free (void *, const char *, int) |
deallocates storage pointed to by p . | |
memory resizing functions: | |
void * | mem_resize (void *, size_t, const char *, int) |
adjust the size of storage pointed to by p to n . | |
memory debugging functions: | |
void | mem_log (FILE *, void(FILE *, const mem_loginfo_t *), void(FILE *, const mem_loginfo_t *)) |
void | mem_leak (void(const mem_loginfo_t *, void *), void *) |
Variables | |
const except_t | mem_exceptfail |
exception for memory allocation failure. |
Header for Memory Management Library (CBL).
#define MEM_FREE | ( | p | ) | ((void)(mem_free((p), __FILE__, __LINE__), (p)=0)) |
deallocates storage pointed to by p
and set it to a null pointer.
See mem_free() for details.
p
must be a modifiable lvalue; a rvalue expression or non-modifiable lvalue like one qualified by const
is not allowed. Also, MEM_FREE() evaluates its argument twice, so an argument containing side effects results in an unpredictable result.
Unchecked errors: foreign value given for p
#define MEM_NEW | ( | p | ) | ((p) = MEM_ALLOC(sizeof *(p))) |
allocates to p
storage whose size is determined by the size of the pointed-to type by p
.
A common way to allocate storage to a pointer p
is as follows:
type *p;
p = malloc(sizeof(type));
However, this is error-prone; it might cause the memory corrupted if one forget to change every instance of type
when the type of p
changes to, say, another_type
. To preclude problems like this a proposed way to allocate storage for a pointer p
is:
p = malloc(sizeof(*p));
In this code, changing the type of p
is automatically reflected to the allocation code above. Note that the expression given in the sizeof
expression is not evaluated, so the validity of p's
value does not matter here.
The macro MEM_NEW() is provided to facilitate such usage. It takes a pointer as an argument and allocates to it storage whose size is the size of the referrenced type. Therefore it makes an invalid call to invoke MEM_NEW() with a pointer to an imconplete type like a pointer to void
and a pointer to a structure whose type definition is not visible.
Note that the sizeof
operator does not evaluate its operand, which makes MEM_NEW() evaluate its argument exactly once as an actual function does. Embedding a side effect in the argument, however, is discouraged.
Possible exceptions: mem_exceptfail
Unchecked errors: none
#define MEM_NEW0 | ( | p | ) | ((p) = MEM_CALLOC(1, sizeof *(p))) |
#define MEM_RESIZE | ( | p, | |||
n | ) | ((p) = mem_resize((p), (n), __FILE__, __LINE__)) |
adjusts the size of storage pointed to by p
to n
bytes.
See mem_resize() for details.
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: foreign value given for p
void* mem_alloc | ( | size_t | n, | |
const char * | file, | |||
int | line | |||
) |
allocates storage of the size n
in bytes.
mem_alloc() does the same job as malloc() except:
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: none
[in] | n | size in bytes for storage to be allocated |
[in] | file | file name in which storage requested |
[in] | func | function name in which strage requested (if C99 supported) |
[in] | line | line number on which storage requested |
n
in bytes.Some general explanation on mem_alloc() can be found on the production version of the library.
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: none
[in] | n | size of memory block requested |
[in] | file | file name in which allocation requested |
[in] | func | function name in which allocation requested (if C99 supported) |
[in] | line | linu number on which allocation requested |
void* mem_calloc | ( | size_t | c, | |
size_t | n, | |||
const char * | file, | |||
int | line | |||
) |
allocates zero-filled storage of the size c
* n
in bytes.
mem_calloc() does the same job as mem_alloc() except that the storage it allocates are zero- filled. The similar explanation as for mem_alloc() applies to mem_calloc() too; see mem_alloc() for details.
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: none
[in] | c | number of items to be allocated |
[in] | n | size in bytes for one item |
[in] | file | file name in which storage requested |
[in] | func | function name in which strage requested (if C99 supported) |
[in] | line | line number on which storage requested |
c
* n
in bytes.
mem_calloc() returns a zero-filled memory block whose size is at least n
. mem_calloc() allocates a memory block by invoking mem_malloc() and set its every byte to zero by memset(). The similar explanation as for mem_alloc() applies to mem_calloc() too; see mem_alloc().
Possible exceptions: assert_exceptfail, mem_exceptfail
Unchecked errors: none
[in] | c | number of items to be allocated |
[in] | n | size in bytes for one item |
[in] | file | file name in which allocation requested |
[in] | func | function name in which allocation requested (if C99 supported) |
[in] | line | line number on which allocation requested |
c
* n
in bytes, which allows no overflow in computing the multiplication. So overflow checking is necessary to mimic the behavior of calloc().
void mem_free | ( | void * | p, | |
const char * | file, | |||
int | line | |||
) |
deallocates storage pointed to by p
.
mem_free() is a simple wrapper function for free().
The additional parameters, file
, func
(if C99 supported), line
are for the consistent form in the calling sites; the debugging version of this library takes advantage of them to raise an exception when something goes wrong in mem_free(). When using the debugging version, some of the following unchecked errors are to be detected.
Possible exceptions: none
Unchecked errors: foreign value given for p
[in] | p | pointer to storage to release |
[in] | file | file name in which deallocation requested |
[in] | func | function name in which deallocation requested (if C99 supported) |
[in] | line | line number on which deallocation requested |
p
.mem_free() releases a given memory block.
Possible exceptions: assert_exceptfail
Unchecked errors: none
[in] | p | pointer to memory block to release (to mark as "freed") |
[in] | file | file name in which deallocation requested |
[in] | func | function name in which deallocation requested (if C99 supported) |
[in] | line | line number on which deallocation is requested |
void* mem_resize | ( | void * | p, | |
size_t | n, | |||
const char * | file, | |||
int | line | |||
) |
adjust the size of storage pointed to by p
to n
.
mem_resize() does the main job of realloc(); adjusting the size of storage already allocated by mem_alloc() or mem_calloc(). While realloc() deallocates like free() when the given size is 0 and allocates like malloc() when the given pointer is a null pointer, mem_resize() accepts neither a null pointer nor zero as its arguments. The similar explanation as for mem_alloc() also applies to mem_resize(). See mem_alloc() for details.
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: foreign value given for p
[in] | p | pointer to storage whose size to be adjusted |
[in] | n | new size for storage |
[in] | file | file name in which adjustment requested |
[in] | func | function name in which adjustment requested (if C99 supported) |
[in] | line | line number on which adjustment requested |
p
to n
.mem_resize() does the main job of realloc(); adjusting the size of the memory block already allocated by mem_alloc() or mem_calloc(). While realloc() deallocates like free() when the given size is 0 and allocates like malloc() when the given pointer is a null pointer, mem_resize() accepts neither a null pointer nor zero as its arguments. The similar explanation as for mem_alloc() also applies to mem_resize(). See mem_alloc() for details.
Possible exceptions: mem_exceptfail, assert_exceptfail
Unchecked errors: none
[in] | p | pointer to memory block whose size to be adjusted |
[in] | n | new size for memory block |
[in] | file | file name in which adjustment requested |
[in] | func | function name in which adjustment requested (if C99 supported) |
[in] | line | line number on which adjustment requested |