Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Created August 6, 2022 23:21
Show Gist options
  • Save AnthonyMikh/9e4c9bb99e4ef7be5fb6f02a5f9d9a01 to your computer and use it in GitHub Desktop.
Save AnthonyMikh/9e4c9bb99e4ef7be5fb6f02a5f9d9a01 to your computer and use it in GitHub Desktop.
Typed versions of C memory managing utilities
#include <cstddef>
#include <cstring>
#include <cstdlib>
// #define TYPED_TIGHT_MALLOC
namespace typed {
template <typename T>
T* memset_n(T *dest, int ch, std::size_t count) {
return static_cast<T*>(std::memset(dest, ch, count * sizeof(T)));
}
template <typename T>
T* memset(T *dest, int ch) {
return memset_n(dest, ch, 1);
}
template <typename T>
T* memcpy_n(T* dest, const T* src, std::size_t count) {
return static_cast<T*>(std::memcpy(dest, src, count * sizeof(T)));
}
template <typename T>
T* memcpy(T* dest, const T* src) {
return memcpy_n(dest, src, 1);
}
template <typename T>
T* memmove_n(T* dest, const T* src, std::size_t count) {
return static_cast<T*>(std::memmove(dest, src, count * sizeof(T)));
}
// due to strict aliasing rules typed memmove makes little sense
// template <typename T>
// T* memmove(T* dest, const T* src) {
// return memmove_n(dest, src, 1);
// }
#ifdef TYPED_TIGHT_MALLOC
template<typename T>
T* malloc_n(std::size_t count) {
return static_cast<T*>(aligned_alloc(alignof(T), count * sizeof(T)));
}
#else
template<typename T>
T* malloc_n(std::size_t count) {
return static_cast<T*>(std::malloc(count * sizeof(T)));
}
#endif
template<typename T>
T* malloc() {
return malloc_n<T>(1);
}
template<typename T>
T* calloc_n(std::size_t count) {
return static_cast<T*>(std::calloc(count, sizeof(T)));
}
template<typename T>
T* calloc() {
return calloc_n<T>(1);
}
template <typename T>
T* realloc(T* ptr, std::size_t count) {
return static_cast<T*>(std::realloc(ptr, count * sizeof(T)));
}
} // namespace typed
// usage example
struct A {
int a;
int b;
};
void zeroify(A* a) {
typed::memset(a, 0);
}
void zeroify_3(A* a) {
typed::memset_n(a, 0, 3);
}
void copy_a(A* dest, const A* src) {
typed::memcpy(dest, src);
}
void copy_a_3(A* dest, const A* src) {
typed::memcpy_n(dest, src, 3);
}
void move_a_64(A* dest, const A* src) {
typed::memmove_n(dest, src, 64);
}
void alloc_and_free() {
auto p = typed::malloc<A>();
free(p);
auto pp = typed::malloc_n<A>(64);
free(pp);
auto pz = typed::calloc<A>();
free(pz);
auto original = typed::calloc_n<A>(4);
auto resized = typed::realloc(original, 8);
if (resized == nullptr) {
free(original);
} else {
free(resized);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment