Created
September 7, 2013 15:13
-
-
Save aperezdc/6476449 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* allocator-test.cc | |
* Copyright (C) 2013 Adrian Perez <[email protected]> | |
* | |
* Distributed under terms of the MIT license. | |
*/ | |
#include <cstdlib> | |
#include <cstdio> | |
struct Allocator | |
{ | |
void* (*alloc) (void*, size_t); | |
void (*free ) (void*, void*); | |
void* userdata; | |
static Allocator Default; | |
}; | |
template <typename T> | |
void Delete(Allocator& alloc, T*& obj) | |
{ | |
obj->~T(); | |
(*alloc.free) (alloc.userdata, obj); | |
obj = 0; // Clean up the pointer | |
} | |
static void* | |
std_alloc(void*, size_t size) | |
{ | |
void* p = malloc(size); | |
printf("%s: allocated %p, %lu bytes\n", __func__, p, size); | |
return p; | |
} | |
static void | |
std_free(void*, void* p) | |
{ | |
free(p); | |
printf("%s: freed %p\n", __func__, p); | |
} | |
Allocator Allocator::Default = | |
{ | |
std_alloc, | |
std_free, | |
NULL, | |
}; | |
class Malloced { | |
public: | |
void* operator new(size_t size, Allocator& alloc) { | |
return (*alloc.alloc) (alloc.userdata, size); | |
} | |
void operator delete(void* p, Allocator& alloc) { | |
// Used when the above throws exceptions | |
return (*alloc.free) (alloc.userdata, p); | |
} | |
void operator delete(void*) { | |
printf("%s <-- SHOULD NOT HAPPEN\n", __PRETTY_FUNCTION__); | |
} | |
}; | |
class Foo : public Malloced { | |
public: | |
Foo() { | |
printf("%s\n", __PRETTY_FUNCTION__); | |
} | |
virtual ~Foo() { | |
printf("%s\n", __PRETTY_FUNCTION__); | |
} | |
}; | |
class Bar : public Foo | |
{ | |
public: | |
Bar(int x): Foo() { | |
printf("%s (x=%i)\n", __PRETTY_FUNCTION__, x); | |
} | |
virtual ~Bar() { | |
printf("%s\n", __PRETTY_FUNCTION__); | |
} | |
}; | |
int main() | |
{ | |
Foo *f = new(Allocator::Default) Foo(); | |
Delete(Allocator::Default, f); | |
f = new(Allocator::Default) Bar(42); | |
Delete(Allocator::Default, f); | |
f = new(Allocator::Default) Bar(666); | |
delete f; // Whoops, would print "SHOULD NOT HAPPEN" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment