initial commit

This commit is contained in:
MarcUs7i 2025-03-08 13:36:49 +01:00
parent 2ec9609b51
commit 670c97dd16
15 changed files with 2373 additions and 2373 deletions

170
.gitignore vendored
View file

@ -1,85 +1,85 @@
# specific name of executable generated
toh_main_driver
toh_test_driver
# Created by https://www.gitignore.io/api/c++,macos,linux
# Edit at https://www.gitignore.io/?templates=c++,macos,linux
### C++ ###
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# End of https://www.gitignore.io/api/c++,macos,linux
# specific name of executable generated
toh_main_driver
toh_test_driver
# Created by https://www.gitignore.io/api/c++,macos,linux
# Edit at https://www.gitignore.io/?templates=c++,macos,linux
### C++ ###
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# End of https://www.gitignore.io/api/c++,macos,linux

3130
Doxyfile

File diff suppressed because it is too large Load diff

View file

@ -1,44 +1,44 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/KWNqcTtj)
### if.03.22 Procedural Programming
# Assignment Simple Memory Manager
With this assignment you shall implement a simple memory manager in C.
## Assignment Objective
Implementation of a memory management system as a replacement for malloc and free.
## Assignment
Technical details regarding the implementation of the memory manager are stated in file `mem_man.c`.
- Implement all functions declared in `mem_man.h`.
- Implement unit tests, at least those that are declared in `test_mem_man.h`
- Add additional unit tests as needed.
## Working Instructions
1. Implement all missing but required functions of all files mentioned below empty to make the
application compilable and runnable. Most unit tests will be red.
**--COMMIT--**
1. 'test_mem_man.c': Implement all declared unit tests. Run those tests, they shall be red, because non of the tested functions is implemented yet.
**--COMMIT--**
1. 'mem_man.c': Implement all functions defined by this file.
- Obey comments in header files and source code.
- Run the unit tests frequently and fix failures.
- Make all unit tests green.
**--COMMIT--**
1. 'test_mem_man.c': Extend the unit tests with additional test cases.
**--COMMIT--**
1. 'mem_man_app.c': Implement the main application according to the requirements state in the source file of the application.
**--COMMIT--**
1. Run and stabilize the application.
## Notes
- `general.h` contains macros for finding the minimum, maximum, and absolute value
- make clean test: This new make target for clearing the console, building, and running unit test is available.
- Sometimes changes are not properly detected by incremental builds. If something very strange
happens during compilation, try to run `make clean` followed by `make` to start a clean build.
This approach is also recommended after everything is done, because some compiler warning appears
only in clean builds.
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/KWNqcTtj)
### if.03.22 Procedural Programming
# Assignment Simple Memory Manager
With this assignment you shall implement a simple memory manager in C.
## Assignment Objective
Implementation of a memory management system as a replacement for malloc and free.
## Assignment
Technical details regarding the implementation of the memory manager are stated in file `mem_man.c`.
- Implement all functions declared in `mem_man.h`.
- Implement unit tests, at least those that are declared in `test_mem_man.h`
- Add additional unit tests as needed.
## Working Instructions
1. Implement all missing but required functions of all files mentioned below empty to make the
application compilable and runnable. Most unit tests will be red.
**--COMMIT--**
1. 'test_mem_man.c': Implement all declared unit tests. Run those tests, they shall be red, because non of the tested functions is implemented yet.
**--COMMIT--**
1. 'mem_man.c': Implement all functions defined by this file.
- Obey comments in header files and source code.
- Run the unit tests frequently and fix failures.
- Make all unit tests green.
**--COMMIT--**
1. 'test_mem_man.c': Extend the unit tests with additional test cases.
**--COMMIT--**
1. 'mem_man_app.c': Implement the main application according to the requirements state in the source file of the application.
**--COMMIT--**
1. Run and stabilize the application.
## Notes
- `general.h` contains macros for finding the minimum, maximum, and absolute value
- make clean test: This new make target for clearing the console, building, and running unit test is available.
- Sometimes changes are not properly detected by incremental builds. If something very strange
happens during compilation, try to run `make clean` followed by `make` to start a clean build.
This approach is also recommended after everything is done, because some compiler warning appears
only in clean builds.

View file

@ -1,14 +1,14 @@
code {
background: #eaeaea;
padding: 0 0.3em;
border-radius: 4px;
}
div.fragment {
padding: 0.5em;
border-radius: 4px;
margin: 1em 0;
}
div.line {
line-height: 1.4;
code {
background: #eaeaea;
padding: 0 0.3em;
border-radius: 4px;
}
div.fragment {
padding: 0.5em;
border-radius: 4px;
margin: 1em 0;
}
div.line {
line-height: 1.4;
}

View file

@ -1,22 +1,22 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Exercise Number: n/a
* Title: general.h
* Author: P. Bauer, S. Schraml
* ----------------------------------------------------------
* Description:
* General usable definitions and types.
* ----------------------------------------------------------
*/
#ifndef ___GENERAL_H
#define ___GENERAL_H
/** Convenience macro to get maximum of two numbers */
#define MAX(x, y) ((x) > (y) ? (x) : (y))
/** Convenience macro to get maximum of two numbers */
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/** Convenience macro to get the absolute value of a number */
#define ABS(x) (x < 0 ? (-1*x) : (x))
#endif
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Exercise Number: n/a
* Title: general.h
* Author: P. Bauer, S. Schraml
* ----------------------------------------------------------
* Description:
* General usable definitions and types.
* ----------------------------------------------------------
*/
#ifndef ___GENERAL_H
#define ___GENERAL_H
/** Convenience macro to get maximum of two numbers */
#define MAX(x, y) ((x) > (y) ? (x) : (y))
/** Convenience macro to get maximum of two numbers */
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/** Convenience macro to get the absolute value of a number */
#define ABS(x) (x < 0 ? (-1*x) : (x))
#endif

View file

@ -1,53 +1,53 @@
/**
* @mainpage
* @section intro Introduction
*
* The implementation of a simple memory management system.
*
* @section objective Assignment Objective
*
* Implementation of a memory management system as a replacement for malloc and free.
*
* @section assignment Assignment
*
* Technical details regarding the implementation of the memory manager are stated in
* file `mem_man.c`.
*
* - Implement all functions declared in `mem_man.h`.
* - Implement unit tests, at least those that are declared in `test_mem_man.h`
* - Add additional unit tests as needed.
*
* @section instructions Working Instructions
*
* -# Implement all missing but required functions of all files mentioned below empty to make the
* application compilable and runnable. Most unit tests will be red.
* - **--COMMIT--**
*
* -# 'test_mem_man.c': Implement all declared unit tests. Run those tests, they shall be red, because non of
* the tested functions is implemented yet.
* - **--COMMIT--**
*
* -# 'mem_man.c': Implement all functions defined by this file.
* - Obey comments in header files and source code.
* - Run the unit tests frequently and fix failures.
* - Make all unit tests green.
* - **--COMMIT--**
* -# 'test_mem_man.c': Extend the unit tests with additional test cases.
* - **--COMMIT--**
*
* -# 'mem_man_app.c': Implement the main application according to the requirements state in the source file
* of the application.
* - **--COMMIT--**
*
* -# Run the application.
*
*
* @section notes Notes
* -# `general.h` contains macros for finding the minimum, maximum, and absolute value
* -# make cleantest: This new make target for clearing the console, building, and running unit test is available.
* -# Sometimes changes are not properly detected by incremental builds. If something very strange
* happens during compilation, try to run `make clean` followed by `make` to start a clean build.
* This approach is also recommended after everthing is done, because some compiler warning appears
* only in clean builds.
/**
* @mainpage
* @section intro Introduction
*
* The implementation of a simple memory management system.
*
* @section objective Assignment Objective
*
* Implementation of a memory management system as a replacement for malloc and free.
*
* @section assignment Assignment
*
* Technical details regarding the implementation of the memory manager are stated in
* file `mem_man.c`.
*
* - Implement all functions declared in `mem_man.h`.
* - Implement unit tests, at least those that are declared in `test_mem_man.h`
* - Add additional unit tests as needed.
*
* @section instructions Working Instructions
*
* -# Implement all missing but required functions of all files mentioned below empty to make the
* application compilable and runnable. Most unit tests will be red.
* - **--COMMIT--**
*
* -# 'test_mem_man.c': Implement all declared unit tests. Run those tests, they shall be red, because non of
* the tested functions is implemented yet.
* - **--COMMIT--**
*
* -# 'mem_man.c': Implement all functions defined by this file.
* - Obey comments in header files and source code.
* - Run the unit tests frequently and fix failures.
* - Make all unit tests green.
* - **--COMMIT--**
* -# 'test_mem_man.c': Extend the unit tests with additional test cases.
* - **--COMMIT--**
*
* -# 'mem_man_app.c': Implement the main application according to the requirements state in the source file
* of the application.
* - **--COMMIT--**
*
* -# Run the application.
*
*
* @section notes Notes
* -# `general.h` contains macros for finding the minimum, maximum, and absolute value
* -# make cleantest: This new make target for clearing the console, building, and running unit test is available.
* -# Sometimes changes are not properly detected by incremental builds. If something very strange
* happens during compilation, try to run `make clean` followed by `make` to start a clean build.
* This approach is also recommended after everthing is done, because some compiler warning appears
* only in clean builds.
*/

198
makefile
View file

@ -1,99 +1,99 @@
CC = gcc
CCLINK = g++
LIBS =
CCOPTIONS = -Wall -pedantic -std=gnu11 -g
LDOPTIONS =
BUILD_DIR = build
TEST = mem_man_test_app
PROGRAM = mem_man_app
COMMON_HDRS = general.h
LIBRARY_FILES = shortcut
ASSIGNMENT_HDRS =
ASSIGNMENT_FILES = mem_man
TEST_FILES = test_mem_man
MAIN_DRIVER = mem_man_app
TEST_DRIVER = mem_man_test_driver
LIBRARY_H = $(addsuffix .h, $(LIBRARY_FILES))
ASSIGNMENT_H = $(addsuffix .h, $(ASSIGNMENT_FILES)) $(ASSIGNMENT_HDRS)
ASSIGNMENT_C = $(addsuffix .c, $(ASSIGNMENT_FILES)) $(MAIN_DRIVER).c
HDRS = $(ASSIGNEMT_H) $(SHARED_HDRS) $(COMMON_HDRS) $(LIBRARY_H)
TESTOBJECT = $(addprefix $(BUILD_DIR)/, $(TEST_DRIVER).o)
MAINOBJECT = $(addprefix $(BUILD_DIR)/, $(MAIN_DRIVER).o)
LIBRARY_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(LIBRARY_FILES)))
TEST_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(TEST_FILES)))
MAIN_OBJ = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(ASSIGNMENT_FILES)))
OBJS = $(LIBRARY_OBJS) $(MAIN_OBJ) $(TEST_OBJS)
DOXY = doxygen
all: $(PROGRAM)
./$(PROGRAM)
$(TEST): $(BUILD_DIR) $(OBJS) $(TESTOBJECT)
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(TESTOBJECT)
$(PROGRAM): $(BUILD_DIR) $(OBJS) $(MAINOBJECT)
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(MAINOBJECT)
.PHONY: clean cleanall doxy test setsample setassignment definesample defineassignment assignmentfolder
clean:
rm -f $(PROGRAM) $(TEST) $(TESTOBJECT) $(MAINOBJECT) $(OBJS)
rm -rf $(BUILD_DIR)
rm -f *.o
cleanall: clean
rm -f index.html
rm -rf html
doxy:
$(DOXY)
rm -f index.html
# ln -s html/index.html index.html
test: $(TEST)
./$(TEST)
cleantest: clean
clear
make test
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
$(BUILD_DIR)/%.o: %.c
$(CC) $(CCOPTIONS) -c -o $@ $<
#sets project as sample solution
setsample:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).sample $(name);)
#sets project as assignment
setassignment:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).assignment $(name);)
# defines current state of project as sample solution
definesample:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).sample;)
# defines current sate of project as assignment
defineassignment :
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).assignment;)
# creates a folder which can serve as a publishable assignment
assignmentfolder:
make setassignment
make doxy
rm -rf ../assignment
mkdir ../assignment
cp -R * ../assignment
cp .gitignore ../assignment
rm ../assignment/*.sample
rm ../assignment/*.assignment
make cleanall
CC = gcc
CCLINK = g++
LIBS =
CCOPTIONS = -Wall -pedantic -std=gnu11 -g
LDOPTIONS =
BUILD_DIR = build
TEST = mem_man_test_app
PROGRAM = mem_man_app
COMMON_HDRS = general.h
LIBRARY_FILES = shortcut
ASSIGNMENT_HDRS =
ASSIGNMENT_FILES = mem_man
TEST_FILES = test_mem_man
MAIN_DRIVER = mem_man_app
TEST_DRIVER = mem_man_test_driver
LIBRARY_H = $(addsuffix .h, $(LIBRARY_FILES))
ASSIGNMENT_H = $(addsuffix .h, $(ASSIGNMENT_FILES)) $(ASSIGNMENT_HDRS)
ASSIGNMENT_C = $(addsuffix .c, $(ASSIGNMENT_FILES)) $(MAIN_DRIVER).c
HDRS = $(ASSIGNEMT_H) $(SHARED_HDRS) $(COMMON_HDRS) $(LIBRARY_H)
TESTOBJECT = $(addprefix $(BUILD_DIR)/, $(TEST_DRIVER).o)
MAINOBJECT = $(addprefix $(BUILD_DIR)/, $(MAIN_DRIVER).o)
LIBRARY_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(LIBRARY_FILES)))
TEST_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(TEST_FILES)))
MAIN_OBJ = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(ASSIGNMENT_FILES)))
OBJS = $(LIBRARY_OBJS) $(MAIN_OBJ) $(TEST_OBJS)
DOXY = doxygen
all: $(PROGRAM)
./$(PROGRAM)
$(TEST): $(BUILD_DIR) $(OBJS) $(TESTOBJECT)
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(TESTOBJECT)
$(PROGRAM): $(BUILD_DIR) $(OBJS) $(MAINOBJECT)
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(MAINOBJECT)
.PHONY: clean cleanall doxy test setsample setassignment definesample defineassignment assignmentfolder
clean:
rm -f $(PROGRAM) $(TEST) $(TESTOBJECT) $(MAINOBJECT) $(OBJS)
rm -rf $(BUILD_DIR)
rm -f *.o
cleanall: clean
rm -f index.html
rm -rf html
doxy:
$(DOXY)
rm -f index.html
# ln -s html/index.html index.html
test: $(TEST)
./$(TEST)
cleantest: clean
clear
make test
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
$(BUILD_DIR)/%.o: %.c
$(CC) $(CCOPTIONS) -c -o $@ $<
#sets project as sample solution
setsample:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).sample $(name);)
#sets project as assignment
setassignment:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).assignment $(name);)
# defines current state of project as sample solution
definesample:
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).sample;)
# defines current sate of project as assignment
defineassignment :
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).assignment;)
# creates a folder which can serve as a publishable assignment
assignmentfolder:
make setassignment
make doxy
rm -rf ../assignment
mkdir ../assignment
cp -R * ../assignment
cp .gitignore ../assignment
rm ../assignment/*.sample
rm ../assignment/*.assignment
make cleanall

View file

@ -1,31 +1,31 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Implementation of a simple memory manager.
* ----------------------------------------------------------
*/
#include "mem_man.h"
#include <stdio.h>
#include <string.h>
/**
* The memory manager operates on a global, statically allocated, linear memory partition (array).
* This memory is organized in memory blocks of 32 bits (4 byte), the number of totally
* available blocks is defined by the constant 'MEMORY_BLOCK_CNT'.
* The smallest allocatable memory unit is one block, larger memory units are allocates always
* a multiple of one block. This means, if a memory up to 32 bit is requested, one block is allocated,
* if a memory of size from 33 bits to 64 bits is request, two blocks are allocated, and so one.
*
* Each memory block shall be initialized with the pattern '0xDEADBEEF", freed memory shall be set to
* the pattern '0xAFFEBAFF'. Such regions are easily recognizable in a memory dump.
*
* The housekeeping data (start address and size) of allocated memory units
* shall be maintained in a linked list.
*/
#define MEMORY_BLOCK_CNT 1024;
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Implementation of a simple memory manager.
* ----------------------------------------------------------
*/
#include "mem_man.h"
#include <stdio.h>
#include <string.h>
/**
* The memory manager operates on a global, statically allocated, linear memory partition (array).
* This memory is organized in memory blocks of 32 bits (4 byte), the number of totally
* available blocks is defined by the constant 'MEMORY_BLOCK_CNT'.
* The smallest allocatable memory unit is one block, larger memory units are allocates always
* a multiple of one block. This means, if a memory up to 32 bit is requested, one block is allocated,
* if a memory of size from 33 bits to 64 bits is request, two blocks are allocated, and so one.
*
* Each memory block shall be initialized with the pattern '0xDEADBEEF", freed memory shall be set to
* the pattern '0xAFFEBAFF'. Such regions are easily recognizable in a memory dump.
*
* The housekeeping data (start address and size) of allocated memory units
* shall be maintained in a linked list.
*/
#define MEMORY_BLOCK_CNT 1024;

160
mem_man.h
View file

@ -1,80 +1,80 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Declaration of functions for memory management.
* ----------------------------------------------------------
*/
#ifndef ___MEM_MAN__H
#define ___MEM_MAN__H
#include <stddef.h>
/** The struct providing the memory statistic values */
typedef struct {
size_t total_bytes;
size_t free_bytes;
size_t used_bytes;
size_t larger_free_unit_bytes;
size_t allocated_units_count;
double free_percentage;
} MemStat;
/**
* Allocates a memory block of the given size in bytes
* in a similar way as `malloc(size)`.
*
* @param size The number of bytes to allocate.
* @return The pointer to the allocated memory block or 0,
* if no memory could be allocated.
*/
void* my_alloc(size_t size);
/**
* Releases the addressed memory block that was allocated via function `my_alloc(...)`.
* If the addressed memory is not allocated, a warning is printed.
*
* @param p The pointer to the memory to free.
*/
void my_free(void* p);
/**
* Prints a brief statistic report about memory that reveals the following key values:
* # total available memory in bytes.
* # free (not allocated) memory in bytes.
* # used (allocated) memory in bytes
* # free memory in percentage (0 % to 100%)
* # number of allocated units (continuously allocated portions of the memory, not memory blocks)
* # largest free continuous memory unit in bytes.
*/
MemStat mem_get_statistics();
/**
* Prints the allocated units (continuously allocated portions of the memory, not memory blocks)
* including their start address within the managed memory as well as their size
* ordered by their start address.
*/
void mem_print_units();
/**
* Provides the index of the allocated unit (continuously allocated portions of the memory, not memory blocks)
* the addressed memory belongs to. If the addressed memory is not allocated or the address is outside
* the range of the managed memory, a value less than zero provided.
*
* @param p_mem The pointer to the memory to query.
* @return The unit index the address belongs to or a value less than 0 if the memory is not allocated.
*/
int get_unit_index(void* p_mem);
/**
* Dumps the content of the memory.
*/
void mem_dump();
#endif
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Declaration of functions for memory management.
* ----------------------------------------------------------
*/
#ifndef ___MEM_MAN__H
#define ___MEM_MAN__H
#include <stddef.h>
/** The struct providing the memory statistic values */
typedef struct {
size_t total_bytes;
size_t free_bytes;
size_t used_bytes;
size_t larger_free_unit_bytes;
size_t allocated_units_count;
double free_percentage;
} MemStat;
/**
* Allocates a memory block of the given size in bytes
* in a similar way as `malloc(size)`.
*
* @param size The number of bytes to allocate.
* @return The pointer to the allocated memory block or 0,
* if no memory could be allocated.
*/
void* my_alloc(size_t size);
/**
* Releases the addressed memory block that was allocated via function `my_alloc(...)`.
* If the addressed memory is not allocated, a warning is printed.
*
* @param p The pointer to the memory to free.
*/
void my_free(void* p);
/**
* Prints a brief statistic report about memory that reveals the following key values:
* # total available memory in bytes.
* # free (not allocated) memory in bytes.
* # used (allocated) memory in bytes
* # free memory in percentage (0 % to 100%)
* # number of allocated units (continuously allocated portions of the memory, not memory blocks)
* # largest free continuous memory unit in bytes.
*/
MemStat mem_get_statistics();
/**
* Prints the allocated units (continuously allocated portions of the memory, not memory blocks)
* including their start address within the managed memory as well as their size
* ordered by their start address.
*/
void mem_print_units();
/**
* Provides the index of the allocated unit (continuously allocated portions of the memory, not memory blocks)
* the addressed memory belongs to. If the addressed memory is not allocated or the address is outside
* the range of the managed memory, a value less than zero provided.
*
* @param p_mem The pointer to the memory to query.
* @return The unit index the address belongs to or a value less than 0 if the memory is not allocated.
*/
int get_unit_index(void* p_mem);
/**
* Dumps the content of the memory.
*/
void mem_dump();
#endif

View file

@ -1,25 +1,25 @@
/*-----------------------------------------------------------------------------
* HTBLA-Leonding
*-----------------------------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
*-----------------------------------------------------------------------------
* Description:
* The main application that uses memory manager.
*-----------------------------------------------------------------------------
*/
#include <stdio.h>
/**
* Allocate and free memory in various combinations,
* print statistics after each step,
* dump allocated units and memory content initially, in between and at the end
* of the program.
*/
int main(int argc, char *argv[]) {
/* Your implementation here. */
/*-----------------------------------------------------------------------------
* HTBLA-Leonding
*-----------------------------------------------------------------------------
* Title: Simple Memory Manager.
* Author: */<your name>;/*
*-----------------------------------------------------------------------------
* Description:
* The main application that uses memory manager.
*-----------------------------------------------------------------------------
*/
#include <stdio.h>
/**
* Allocate and free memory in various combinations,
* print statistics after each step,
* dump allocated units and memory content initially, in between and at the end
* of the program.
*/
int main(int argc, char *argv[]) {
/* Your implementation here. */
}

View file

@ -1,29 +1,29 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Tests implementation for memory management.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Unit tests for for memory management.
* ----------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include "shortcut.h"
#include "test_mem_man.h"
int main(int argc, char *argv[])
{
ADD_TEST(test_alloc_memory__shall_allocate_memory);
ADD_TEST(test_alloc_memory__shall_not_allocate_insufficient_memory);
ADD_TEST(test_free_memory__shall_release_allocate_memory);
ADD_TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start);
ADD_TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory);
/* Additional test declarations here */
run_tests();
return 0;
}
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Tests implementation for memory management.
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Unit tests for for memory management.
* ----------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include "shortcut.h"
#include "test_mem_man.h"
int main(int argc, char *argv[])
{
ADD_TEST(test_alloc_memory__shall_allocate_memory);
ADD_TEST(test_alloc_memory__shall_not_allocate_insufficient_memory);
ADD_TEST(test_free_memory__shall_release_allocate_memory);
ADD_TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start);
ADD_TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory);
/* Additional test declarations here */
run_tests();
return 0;
}

View file

@ -1,151 +1,151 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: shortcut.c
* Author: P. Bauer
* Date: November 08, 2010
* ----------------------------------------------------------
* Description:
* Test driver.
* ----------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "shortcut.h"
#define MAX_TEST_FUNCTIONS 256
static char assert_msg_buffer[1024];
static int tc_count = 0;
static int tc_fail_count = 0;
static struct TestCase test_cases[MAX_TEST_FUNCTIONS];
const char* version()
{
return "ShortCut v. 1.3.0";
}
char* format_msg(char* format, ...) {
va_list args;
va_start (args, format);
vsprintf(assert_msg_buffer, format, args);
return assert_msg_buffer;
}
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line)
{
if (!bool_expr) {
if (tc->success) {
tc->success = false;
tc_fail_count++;
}
printf("\n\tFailure (file: %s, line %d): %s: %s", file, line, tc->name, msg);
}
}
void assert_false(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line)
{
assert_true(!bool_expr, tc, msg, file, line);
}
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line);
void assert_equals_str(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
if (expected == actual) {
return;
}
if (expected == 0 || actual == 0) {
assert_string_failure(expected, actual, tc, msg, file, line);
return;
}
if (strcmp(actual, expected) != 0) {
assert_string_failure(expected, actual, tc, msg, file, line);
return;
}
}
#define MAX_MSG_LEN 128
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected \"%s\", actual \"%s\". %s", expected, actual, msg);
assert_true(false, tc, new_msg, file, line);
}
void assert_equals(int expected, int actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected %d, actual %d. %s", expected, actual, msg);
assert_true(expected == actual, tc, new_msg, file, line);
}
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
const char* msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected %f, actual %f. %s", expected, actual, msg);
double min_val = expected - tolerance;
double max_val = expected + tolerance;
assert_true(min_val <= actual && actual <= max_val, tc, new_msg, file, line);
}
int get_test_count()
{
return tc_count;
}
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_name)
{
if (tc_count == MAX_TEST_FUNCTIONS) {
return false;
}
else {
test_cases[tc_count].success = true;
test_cases[tc_count].name = test_name;
test_cases[tc_count].test_function = test_function;
tc_count++;
return true;
}
}
void run_tests()
{
int i;
printf("\n%s: Running tests\n", version());
for (i = 0; i < get_test_count(); i++) {
printf("Running test %s ...", test_cases[i].name);
test_cases[i].test_function(&test_cases[i]);
if (test_cases[i].success) {
printf("\033[32m OK\033[m");
}
else {
printf("\033[31m ... FAIL\033[m");
}
printf("\n");
}
printf("\nTotal tests run: %d\n", tc_count);
if (tc_fail_count > 0) {
printf("\033[31mTests failed: %d\033[m\n", tc_fail_count);
}
else {
printf("\033[32mAll tests run successfully\033[m\n");
}
}
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: shortcut.c
* Author: P. Bauer
* Date: November 08, 2010
* ----------------------------------------------------------
* Description:
* Test driver.
* ----------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "shortcut.h"
#define MAX_TEST_FUNCTIONS 256
static char assert_msg_buffer[1024];
static int tc_count = 0;
static int tc_fail_count = 0;
static struct TestCase test_cases[MAX_TEST_FUNCTIONS];
const char* version()
{
return "ShortCut v. 1.3.0";
}
char* format_msg(char* format, ...) {
va_list args;
va_start (args, format);
vsprintf(assert_msg_buffer, format, args);
return assert_msg_buffer;
}
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line)
{
if (!bool_expr) {
if (tc->success) {
tc->success = false;
tc_fail_count++;
}
printf("\n\tFailure (file: %s, line %d): %s: %s", file, line, tc->name, msg);
}
}
void assert_false(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line)
{
assert_true(!bool_expr, tc, msg, file, line);
}
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line);
void assert_equals_str(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
if (expected == actual) {
return;
}
if (expected == 0 || actual == 0) {
assert_string_failure(expected, actual, tc, msg, file, line);
return;
}
if (strcmp(actual, expected) != 0) {
assert_string_failure(expected, actual, tc, msg, file, line);
return;
}
}
#define MAX_MSG_LEN 128
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected \"%s\", actual \"%s\". %s", expected, actual, msg);
assert_true(false, tc, new_msg, file, line);
}
void assert_equals(int expected, int actual, struct TestCase *tc,
const char *msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected %d, actual %d. %s", expected, actual, msg);
assert_true(expected == actual, tc, new_msg, file, line);
}
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
const char* msg, const char* file, int line)
{
char new_msg[MAX_MSG_LEN];
sprintf(new_msg, "Expected %f, actual %f. %s", expected, actual, msg);
double min_val = expected - tolerance;
double max_val = expected + tolerance;
assert_true(min_val <= actual && actual <= max_val, tc, new_msg, file, line);
}
int get_test_count()
{
return tc_count;
}
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_name)
{
if (tc_count == MAX_TEST_FUNCTIONS) {
return false;
}
else {
test_cases[tc_count].success = true;
test_cases[tc_count].name = test_name;
test_cases[tc_count].test_function = test_function;
tc_count++;
return true;
}
}
void run_tests()
{
int i;
printf("\n%s: Running tests\n", version());
for (i = 0; i < get_test_count(); i++) {
printf("Running test %s ...", test_cases[i].name);
test_cases[i].test_function(&test_cases[i]);
if (test_cases[i].success) {
printf("\033[32m OK\033[m");
}
else {
printf("\033[31m ... FAIL\033[m");
}
printf("\n");
}
printf("\nTotal tests run: %d\n", tc_count);
if (tc_fail_count > 0) {
printf("\033[31mTests failed: %d\033[m\n", tc_fail_count);
}
else {
printf("\033[32mAll tests run successfully\033[m\n");
}
}

View file

@ -1,112 +1,112 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: shortcut
* Author: P. Bauer
* Date: November 03, 2010
* ----------------------------------------------------------
* Description:
* A simple unit testing frame work for C.
* ----------------------------------------------------------
*/
#ifndef ___SHORTCUT_H
#define ___SHORTCUT_H
#include <stdbool.h>
/** TestCase is the struct to define one test case. A test case can
*** be added to a test. If the test is run all added test cases are
*** run and the result of the run of each test case is checked automatically.
*/
struct TestCase {
const char *name;
/** true if the test passed, false otherwise. */
bool success;
/** The test function which is executed by the test framework. */
void (*test_function)(struct TestCase *tc);
};
/**
*** @return Version of shortcut as string
***/
const char* version();
/**
*** @return The fromated string as generated using sprintf(format, ...)
***/
char* format_msg(char* format, ...);
/** assert_true checks, whether a boolean expression passed is true or false.
*** in case it is false the test case stating the assertion is marked
*** as failed and msg is printed.
*** @param bool_expr Expression which is evaluated.
*** @param tc Pointer to the test case which states this assertion.
*** @param msg Message to be printed if assertion evaluates to false.
*** @param file File in which the assert is given.
*** @param line Line in which the assert is given.
*/
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line);
/** assert_false does the same as assert() but the boolean expression
*** has to evaluate to false. If it evaluates to true the assertion
*** fails.
*** @see assert
*/
void assert_false(bool bool_expr, struct TestCase* tc, const char* msg,
const char* file, int line);
/** assert_equals checks whether two values are equal. Currently the following
*** data formats are supported:
*** - strings
*** - integer
*** @param expected The expected string value
*** @param actual The actual string value
*** @param tc Pointer to the test case which states this assertion.
*** @param msg Message to be printed if assertion evaluates to false.
*** @param file File in which the assert is given.
*** @param line Line in which the assert is given.
*** @see assert
*/
void assert_equals(int expected, int actual, struct TestCase* tc,
const char* msg, const char* file, int line);
void assert_equals_str(const char* expected, char* actual, struct TestCase* tc,
const char* msg, const char* file, int line);
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
const char* msg, const char* file, int line);
/** @return The total number of test cases added to the test.
*/
int get_test_count();
/** add_test creates a new test case and adds the a test function to
*** this test case.
*** @param test_function Pointer to the test function to be added
*** to the newly created test case.
*** @param test_case_name Name which should be assigned to the newly
*** created test case.
*/
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_case_name);
void run_tests();
#define TEST(testname) void testname(struct TestCase *tc)
#define MSG(format, ...) format_msg(format, ##__VA_ARGS__)
#define ASSERT_TRUE(condition, msg) assert_true(condition, tc, msg, __FILE__, __LINE__)
#define ASSERT_FALSE(condition, msg) assert_false(condition, tc, msg, __FILE__, __LINE__)
#define ASSERT_EQUALS(expected, actual) assert_equals(expected, actual, tc, "", __FILE__, __LINE__)
#define ASSERT_EQUALS_STR(expected, actual, msg) assert_equals_str(expected, actual, tc, msg, __FILE__, __LINE__)
#define ASSERT_EQUALS_TOLERANCE(expected, actual, tolerance) assert_equals_f(expected, actual, tolerance, tc, "", __FILE__, __LINE__)
#define ASSERT_EQUALS_TOLERANCE_STR(expected, actual, tolerance, msg) assert_equals_f(expected, actual, tolerance, tc, msg, __FILE__, __LINE__)
#define ADD_TEST(testfunction) add_test(testfunction, #testfunction)
#endif
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: shortcut
* Author: P. Bauer
* Date: November 03, 2010
* ----------------------------------------------------------
* Description:
* A simple unit testing frame work for C.
* ----------------------------------------------------------
*/
#ifndef ___SHORTCUT_H
#define ___SHORTCUT_H
#include <stdbool.h>
/** TestCase is the struct to define one test case. A test case can
*** be added to a test. If the test is run all added test cases are
*** run and the result of the run of each test case is checked automatically.
*/
struct TestCase {
const char *name;
/** true if the test passed, false otherwise. */
bool success;
/** The test function which is executed by the test framework. */
void (*test_function)(struct TestCase *tc);
};
/**
*** @return Version of shortcut as string
***/
const char* version();
/**
*** @return The fromated string as generated using sprintf(format, ...)
***/
char* format_msg(char* format, ...);
/** assert_true checks, whether a boolean expression passed is true or false.
*** in case it is false the test case stating the assertion is marked
*** as failed and msg is printed.
*** @param bool_expr Expression which is evaluated.
*** @param tc Pointer to the test case which states this assertion.
*** @param msg Message to be printed if assertion evaluates to false.
*** @param file File in which the assert is given.
*** @param line Line in which the assert is given.
*/
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
const char* file, int line);
/** assert_false does the same as assert() but the boolean expression
*** has to evaluate to false. If it evaluates to true the assertion
*** fails.
*** @see assert
*/
void assert_false(bool bool_expr, struct TestCase* tc, const char* msg,
const char* file, int line);
/** assert_equals checks whether two values are equal. Currently the following
*** data formats are supported:
*** - strings
*** - integer
*** @param expected The expected string value
*** @param actual The actual string value
*** @param tc Pointer to the test case which states this assertion.
*** @param msg Message to be printed if assertion evaluates to false.
*** @param file File in which the assert is given.
*** @param line Line in which the assert is given.
*** @see assert
*/
void assert_equals(int expected, int actual, struct TestCase* tc,
const char* msg, const char* file, int line);
void assert_equals_str(const char* expected, char* actual, struct TestCase* tc,
const char* msg, const char* file, int line);
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
const char* msg, const char* file, int line);
/** @return The total number of test cases added to the test.
*/
int get_test_count();
/** add_test creates a new test case and adds the a test function to
*** this test case.
*** @param test_function Pointer to the test function to be added
*** to the newly created test case.
*** @param test_case_name Name which should be assigned to the newly
*** created test case.
*/
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_case_name);
void run_tests();
#define TEST(testname) void testname(struct TestCase *tc)
#define MSG(format, ...) format_msg(format, ##__VA_ARGS__)
#define ASSERT_TRUE(condition, msg) assert_true(condition, tc, msg, __FILE__, __LINE__)
#define ASSERT_FALSE(condition, msg) assert_false(condition, tc, msg, __FILE__, __LINE__)
#define ASSERT_EQUALS(expected, actual) assert_equals(expected, actual, tc, "", __FILE__, __LINE__)
#define ASSERT_EQUALS_STR(expected, actual, msg) assert_equals_str(expected, actual, tc, msg, __FILE__, __LINE__)
#define ASSERT_EQUALS_TOLERANCE(expected, actual, tolerance) assert_equals_f(expected, actual, tolerance, tc, "", __FILE__, __LINE__)
#define ASSERT_EQUALS_TOLERANCE_STR(expected, actual, tolerance, msg) assert_equals_f(expected, actual, tolerance, tc, msg, __FILE__, __LINE__)
#define ADD_TEST(testfunction) add_test(testfunction, #testfunction)
#endif

View file

@ -1,40 +1,40 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Unit Tests for Memory Manager implementation
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Tests functions for memory manager.
* ----------------------------------------------------------
*/
#include "test_mem_man.h"
#include <stdio.h>
#include <string.h>
TEST(test_alloc_memory__shall_allocate_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_alloc_memory__shall_not_allocate_insufficient_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_release_allocate_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Unit Tests for Memory Manager implementation
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Tests functions for memory manager.
* ----------------------------------------------------------
*/
#include "test_mem_man.h"
#include <stdio.h>
#include <string.h>
TEST(test_alloc_memory__shall_allocate_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_alloc_memory__shall_not_allocate_insufficient_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_release_allocate_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}
TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory) {
/** unit test code here */
ASSERT_TRUE(false, MSG("Not implemented"));
}

View file

@ -1,27 +1,27 @@
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Unit Tests for Memory Manager implementation
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Tests functions for memory manager.
* ----------------------------------------------------------
*/
#ifndef ___TEST_MEM_MAN_H
#define ___TEST_MEM_MAN_H
#include "shortcut.h"
TEST(test_alloc_memory__shall_allocate_memory);
TEST(test_alloc_memory__shall_not_allocate_insufficient_memory);
TEST(test_free_memory__shall_release_allocate_memory);
TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start);
TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory);
/*
Add more unit tests as needed!
Don't forget to register additional tests in test_driver.c
*/
#endif
/*----------------------------------------------------------
* HTBLA-Leonding
* ---------------------------------------------------------
* Title: Unit Tests for Memory Manager implementation
* Author: */<your name>;/*
* ----------------------------------------------------------
* Description:
* Tests functions for memory manager.
* ----------------------------------------------------------
*/
#ifndef ___TEST_MEM_MAN_H
#define ___TEST_MEM_MAN_H
#include "shortcut.h"
TEST(test_alloc_memory__shall_allocate_memory);
TEST(test_alloc_memory__shall_not_allocate_insufficient_memory);
TEST(test_free_memory__shall_release_allocate_memory);
TEST(test_free_memory__shall_ignore_release_if_allocated_memory_is_not_start);
TEST(test_free_memory__shall_ignore_release_for_not_allocated_memory);
/*
Add more unit tests as needed!
Don't forget to register additional tests in test_driver.c
*/
#endif