lib<fancy_memory> 0.1.0
A very simple, very experimental C library for tracking dynamically allocated memory
Loading...
Searching...
No Matches
Typedefs | Functions
fancy_memory.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

Go to the source code of this file.

Typedefs

typedef struct fancy_memory_s fancy_memory_t
 An opaque data type that is used as a container for storing "memory tracking" related data, and which type gets passed, as a pointer argument, to the library's methods for state interrogation and mutation.
 

Functions

void fancy_memory_get_library_version (uint16_t *major, uint16_t *minor, uint16_t *revision)
 A method that can be used to retrieve the library's current version. It works by populating the arguments major , minor , and revision with the library's major, minor, revision version numbers, respectively.
 
fancy_memory_tfancy_memory_create (void)
 The factory method that needs to be used in order to instantiate a fancy_memory_t object.
 
void fancy_memory_destroy (fancy_memory_t *self)
 The method that should be used to destroy a fancy_memory_t object once that object is no longer needed.
 
voidfancy_memory_malloc (fancy_memory_t *self, size_t size)
 The method that must be used to allocate and track new memory.
 
void fancy_memory_free (fancy_memory_t *self, void *pointer)
 The method that must be used to free (and stop tracking) memory previously allocated using the same fancy_memory_t instance (i.e., the object pointed to by self ).
 
voidfancy_memory_realloc (fancy_memory_t *self, void *pointer, size_t size)
 The method that must be used to reallocate (and update the tracking information of) memory that was initially allocated using the same fancy_memory_t instance (i.e., the object pointed to by self ).
 
void fancy_memory_debug (fancy_memory_t const *self, FILE *stream)
 A method that can be used to print (i.e., write) a summary of the tracked memory for self .
 
size_t fancy_memory_get_total (fancy_memory_t const *self)
 The method that must be used to retrieve the total amount of memory (in bytes) currently being tracked by the fancy_memory_t object self .
 

Typedef Documentation

◆ fancy_memory_t

typedef struct fancy_memory_s fancy_memory_t

An opaque data type that is used as a container for storing "memory tracking" related data, and which type gets passed, as a pointer argument, to the library's methods for state interrogation and mutation.

Note
This object should always be created using the fancy_memory_create() factory method.
See also
fancy_memory_create
Example:
/*
Copyright (c) 2023 BB-301 <fw3dg3@gmail.com>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the “Software”), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include "fancy_memory.h"
#define MY_MESSAGE "hello"
#define MY_MESSAGE_SUFFIX " world"
int main(void)
{
// We first start by checking which library version we are using.
uint16_t major, minor, revision;
fancy_memory_get_library_version(&major, &minor, &revision);
// And we print that version to `stdout`.
fprintf(
"Current lib<fancy_memory> library version: %d.%d.%d\n",
major,
minor,
revision);
// We instantiate the memory tracker object.
fancy_memory_t *memory_tracker = fancy_memory_create();
// At this point, the tracker is empty (i.e., no allocation
// has been made yet).
assert(fancy_memory_get_total(memory_tracker) == 0);
// We allocate (and track) memory to be able copy `MY_MESSAGE` into
// a string. We store the allocated memory's address in a variable
// named `my_string`.
char *my_string = fancy_memory_malloc(memory_tracker, sizeof(char) * (strlen(MY_MESSAGE) + 1));
// We populate, using `strcpy`, the newly allocated memory with `MY_MESSAGE`.
strcpy(my_string, MY_MESSAGE);
// We print that string to `stdout`.
fprintf(stdout, "my_string = %s\n", my_string);
// We use the "debug" library method to print a summary of the tracked
// memory to `stdout`.
fancy_memory_debug(memory_tracker, stdout);
// We can also confirm that we are currently tracking `strlen(MY_MESSAGE) + 1`
// bytes in total.
assert(fancy_memory_get_total(memory_tracker) == (strlen(MY_MESSAGE) + 1));
// We make a second, 4-byte allocation.
uint8_t *my_bytes = fancy_memory_malloc(memory_tracker, sizeof(uint8_t) * 4);
// We confirm that our total (tracked) memory usage has grown by 4 bytes.
assert(fancy_memory_get_total(memory_tracker) == (strlen(MY_MESSAGE) + 1 + 4));
// We can now look at the summary to see that it has been updated with more
// information.
fancy_memory_debug(memory_tracker, stdout);
// We get rid of the memory pointed to by `my_bytes`.
fancy_memory_free(memory_tracker, my_bytes);
// We confirm that we are back at 4 bytes less.
assert(fancy_memory_get_total(memory_tracker) == (strlen(MY_MESSAGE) + 1));
// We want to append the string value contained in the
// `MY_MESSAGE_SUFFIX` macro at the end of the string
// pointed to by `my_string`, so we make a reallocation.
my_string = fancy_memory_realloc(
memory_tracker, my_string,
sizeof(char) * (strlen(MY_MESSAGE) + strlen(MY_MESSAGE_SUFFIX) + 1));
// And we use `memcpy` to populate the suffix bytes.
memcpy((my_string + strlen(MY_MESSAGE)), MY_MESSAGE_SUFFIX, strlen(MY_MESSAGE_SUFFIX));
my_string[strlen(MY_MESSAGE) + strlen(MY_MESSAGE_SUFFIX) + 1] = '\0';
// We print the updated string to `stdout`.
fprintf(stdout, "my_string = %s\n", my_string);
// We confirm that our total (tracked) memory usage has grown by strlen(MY_MESSAGE_SUFFIX) bytes.
assert(fancy_memory_get_total(memory_tracker) == (strlen(MY_MESSAGE) + strlen(MY_MESSAGE_SUFFIX) + 1));
// And we look at the summary to see that it has been updated, again...
fancy_memory_debug(memory_tracker, stdout);
// We free the memory pointed to by `my_string`.
fancy_memory_free(memory_tracker, my_string);
// At this point, the tracker is empty again.
assert(fancy_memory_get_total(memory_tracker) == 0);
// And we look at the summary one last time.
fancy_memory_debug(memory_tracker, stdout);
// We have reached the end of the program, so we destroy
// the memory tracker object. NOTE: In most cases, this won't
// be necessary, but we do it here to have a complete example
// where all of the library's methods and types are used.
fancy_memory_destroy(memory_tracker);
// We terminate the process.
exit(EXIT_SUCCESS);
}
fancy_memory_t * fancy_memory_create(void)
The factory method that needs to be used in order to instantiate a fancy_memory_t object.
void fancy_memory_free(fancy_memory_t *self, void *pointer)
The method that must be used to free (and stop tracking) memory previously allocated using the same f...
void fancy_memory_debug(fancy_memory_t const *self, FILE *stream)
A method that can be used to print (i.e., write) a summary of the tracked memory for self .
void * fancy_memory_malloc(fancy_memory_t *self, size_t size)
The method that must be used to allocate and track new memory.
struct fancy_memory_s fancy_memory_t
An opaque data type that is used as a container for storing "memory tracking" related data,...
Definition: fancy_memory.h:48
void fancy_memory_get_library_version(uint16_t *major, uint16_t *minor, uint16_t *revision)
A method that can be used to retrieve the library's current version. It works by populating the argum...
void * fancy_memory_realloc(fancy_memory_t *self, void *pointer, size_t size)
The method that must be used to reallocate (and update the tracking information of) memory that was i...
void fancy_memory_destroy(fancy_memory_t *self)
The method that should be used to destroy a fancy_memory_t object once that object is no longer neede...
size_t fancy_memory_get_total(fancy_memory_t const *self)
The method that must be used to retrieve the total amount of memory (in bytes) currently being tracke...
FILE stdout

Function Documentation

◆ fancy_memory_create()

fancy_memory_t * fancy_memory_create ( void  )

The factory method that needs to be used in order to instantiate a fancy_memory_t object.

Returns
fancy_memory_t* A pointer to the created fancy_memory_t object.
Examples
examples/demo.c.

◆ fancy_memory_debug()

void fancy_memory_debug ( fancy_memory_t const *  self,
FILE stream 
)

A method that can be used to print (i.e., write) a summary of the tracked memory for self .

Parameters
selfA pointer to the fancy_memory_t instance for which to print a summary.
streamA pointer to a writable stream (e.g., stdout, or a file pointer to a text file) to which to print the summary.
Examples
examples/demo.c.

◆ fancy_memory_destroy()

void fancy_memory_destroy ( fancy_memory_t self)

The method that should be used to destroy a fancy_memory_t object once that object is no longer needed.

Parameters
selfA pointer to the fancy_memory_t instance to be destroyed.
Note
Destroying the object will not free the tracked memory (i.e., the memory that was allocated using the fancy_memory_malloc and fancy_memory_realloc methods): it will only free the memory used to track that memory (i.e., the memory contained inside the fancy_memory_t object).
Examples
examples/demo.c.

◆ fancy_memory_free()

void fancy_memory_free ( fancy_memory_t self,
void pointer 
)

The method that must be used to free (and stop tracking) memory previously allocated using the same fancy_memory_t instance (i.e., the object pointed to by self ).

Parameters
selfA pointer to the fancy_memory_t instance that was initially used when allocating the memory pointed to by pointer .
pointerA pointer to the memory to be freed, which was previously allocated using the fancy_memory_t instance pointed to by self .
Warning
Passing a pointer to memory that was not initially allocated using self will result in the process being terminated.
Note
Internally, this method makes a call to free().
See also
fancy_memory_malloc, fancy_memory_realloc
Examples
examples/demo.c.

◆ fancy_memory_get_library_version()

void fancy_memory_get_library_version ( uint16_t major,
uint16_t minor,
uint16_t revision 
)

A method that can be used to retrieve the library's current version. It works by populating the arguments major , minor , and revision with the library's major, minor, revision version numbers, respectively.

Parameters
majorA pointer to a uint16_t value to which the "major" version number will be written.
minorA pointer to a uint16_t value to which the "minor" version number will be written.
revisionA pointer to a uint16_t value to which the "revision" version number will be written.
Examples
examples/demo.c.

◆ fancy_memory_get_total()

size_t fancy_memory_get_total ( fancy_memory_t const *  self)

The method that must be used to retrieve the total amount of memory (in bytes) currently being tracked by the fancy_memory_t object self .

Parameters
selfA pointer to the fancy_memory_t instance for which to retrieve to total memory usage.
Returns
size_t The total number of bytes currently being tracked (i.e., that have been allocated but not yet freed) using self .
Examples
examples/demo.c.

◆ fancy_memory_malloc()

void * fancy_memory_malloc ( fancy_memory_t self,
size_t  size 
)

The method that must be used to allocate and track new memory.

Parameters
selfA pointer to the fancy_memory_t instance to be used to track the new memory.
sizeThe size of the memory to be allocated (and returned).
Returns
void* A pointer to the newly allocated memory.
Note
- Internally, this method makes a call to malloc().
- If, internally, malloc() returns the NULL pointer, this method will terminate the process.
See also
fancy_memory_realloc, fancy_memory_free
Examples
examples/demo.c.

◆ fancy_memory_realloc()

void * fancy_memory_realloc ( fancy_memory_t self,
void pointer,
size_t  size 
)

The method that must be used to reallocate (and update the tracking information of) memory that was initially allocated using the same fancy_memory_t instance (i.e., the object pointed to by self ).

Parameters
selfA pointer to the fancy_memory_t instance that was used when initially allocating the memory pointed to by pointer .
pointerA pointer to the memory to be reallocated, which was initially allocated using the fancy_memory_t instance pointed to by self .
sizeThe size to be used for the re-allocation.
Returns
void* A pointer to the re-allocated memory.
Warning
Passing a pointer to memory that was not initially allocated using self will result in the process being terminated.
Note
- Internally, this method makes a call to realloc().
- If, internally, realloc() returns the NULL pointer, this method will terminate the process.
See also
fancy_memory_malloc, fancy_memory_free
Examples
examples/demo.c.