Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Last active March 7, 2016 05:29
Show Gist options
  • Save andrewrk/b2f363a413d82b5a3d90 to your computer and use it in GitHub Desktop.
Save andrewrk/b2f363a413d82b5a3d90 to your computer and use it in GitHub Desktop.
create and destroy working in C++ without libstdc++
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <new>
// compile and run:
// g++ -std=c++11 -nodefaultlibs -fno-exceptions -fno-rtti -o test.o -c test.cpp && gcc -o test test.o && ./test
static void panic(const char *format, ...) __attribute__ ((noreturn)) __attribute__ ((format (printf, 1, 2)));
static void panic(const char *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap);
abort();
}
// It's safe to use stdlib free() to free the ptr returned by allocate().
// however, since allocated memory created with create() must be freed with
// destroy(), you might consider always using destroy() to free memory for
// consistency's sake. I have verified that calling the constructor and
// destructor of a primitive type does nothing, and generated code using
// create()/destroy() for primitive types is identical to generated code using
// allocate()/free()
template<typename T>
static inline T *allocate(size_t count) {
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
if (!ptr)
panic("allocate: out of memory");
return ptr;
}
// allocates enough memory for T and then calls the constructor of T.
// use destroy() to free the memory when done.
template<typename T, typename... Args>
static inline T *create(Args... args) {
T *ptr = allocate<T>(1);
new (ptr) T(args...);
return ptr;
}
// calls the destructor of T and then frees the memory
template<typename T>
static inline void destroy(T *ptr) {
ptr->T::~T();
free(ptr);
}
class Foo {
public:
Foo(int x, const char *str) : xyz(x) { fprintf(stderr, "constructor %d %s\n", x, str); }
~Foo() { fprintf(stderr, "destructor\n"); }
void bar() { fprintf(stderr, "bar %d\n", xyz); }
private:
int xyz;
};
int main(int argc, char *argv[]) {
Foo *foo = create<Foo>(19, "baz");
foo->bar();
destroy(foo);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment