Reputation: 669
I am writing a memory testing framework, in which I replace dynamic memory allocation functions with my own (eg. malloc, realloc, free, etc.). However, the system expects static functions (I can not change this).
I have a MemoryTester class, which logs the memory calls, and I want to bind its member function implementations of the memory allocation functions. Is this possible with C++?
EDIT:
Here is some code highlighting what I'm trying to do:
typedef void*(allocateFuncPtr) (uint8_t);
typedef void (freeFuncPtr) (void*);
void setAllocateFunction(allocateFuncPtr) {...}
void setFreeFunction(freeFuncPtr) {...}
class MemoryTester
{
void *malloc(uint8_t size);
void free(void *ptr);
}
int main()
{
MemoryTester *tester = new MemoryTester();
//want to set allocate and free functions to those in tester
setAllocateFunction( tester->getAllocateFunction() );
setFreeFunction( tester->getFreeFunction() );
return 0;
}
Upvotes: 4
Views: 2726
Reputation: 14212
If your compiler supports 0x lambdas, you can use a closure:
int main() {
MemoryTester tester; // If no need for dynamic allocation, don't use it.
setAllocateFunction([&tester](uint8_t size) { return tester.malloc(size); });
setFreeFunction([&tester](void *p) { tester.free(p); });
return 0;
}
No changes required to your MemoryTester class nor whichever library setAllocateFunction & setFreeFunction belong to.
Without lambdas, instead of a singleton class, use a single global object:
struct MemoryTester {
void* malloc(uint8_t size); // Neither are static.
void free(void *p);
};
MemoryTester tester_a;
void* tester_a_malloc(uint8_t size) { return tester_a.malloc(size); }
void tester_a_free(void *p) { return tester_a.free(p); }
int main() {
setAllocateFunction(&tester_a_malloc);
setFreeFunction(&tester_a_free);
}
The advantage here is the entire MemoryTester class isn't hamstrung because of one particular need for it. You can create more functions (e.g. tester_b_malloc/free) as needed to accommodate other uses within the same program.
Upvotes: 3
Reputation: 208353
After the edit, the intent seems clearer to me. The simplest thing that you can do is using static member functions in the MemoryTester
instead of non-static member functions. If they need to hold state, that state will have to be moved to be static
members of the class.
Upvotes: 3
Reputation: 6916
If you are using GCC, then you can have the linker wrap the function for you with the --wrap option ( or -Wl,--wrap,malloc ).
Then you can intercept calls to malloc because all calls to that function will be redirected to __wrap_malloc. You can call the real (original c-lib) malloc function using the name __real_malloc or you can substitute a replacement of your own (and if __real_malloc isn't called, then the linker may be able to dead-strip out the original c-lib malloc all-together).
void *__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
FWIW, you can replace the global new and delete operations and then you can have a program using only your own memory system (even when you use code from 3rd party compiled libraries as long as they haven't overloaded global new and delete).
Here's some great info: Tutorial of Replacing "new" and "delete"
Upvotes: 1
Reputation: 146930
Not unless you make a global object. If the framework takes regular function pointers, then you're stuck with what it provides, and if it doesn't provide for the traditional void* userdata style, then you're stuffed, or it's global object time.
Upvotes: 0
Reputation: 69682
If I understand correctly what you ask, there is no "binding" to do. Once the memory have been allocated, you can tell the compiler it's type by user a cast, in your case a reinterpret_cast. For example, in you allocation function:
unsigned char* raw_memory = allocation( std::size_t );
MyFinalType* object = reinterpret_cast<MyFinalType*>(raw_memory); // tells the compiler to take this memory as a MyFinalType.
Then you return your final type.
To know wich type to use, you'll certainly want to use templates.
Don't forget that C++ is a statically typed language: you can't bind functions to an object type. Ok you can, but the, you have to use std::function or function pointers, that are not what you want here.
Upvotes: 0
Reputation: 16761
Have one singleton MemoryTester object, and have bridge static functions that call member functions of that object.
Upvotes: -2