我正在编写一个内存测试框架,在其中我用自己的内存替换动态内存分配函数(例如,malloc,realloc,free等)。但是,系统需要静态函数(我不能改变它)。
我有一个MemoryTester类,它记录内存调用,我想绑定其内存分配函数的成员函数实现。这可能用C ++吗?
编辑:
这是一些突出我正在尝试做的代码:
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;
}
答案 0 :(得分:3)
编辑后,意图对我来说更清晰。您可以做的最简单的事情是在MemoryTester
中使用静态成员函数而不是非静态成员函数。如果他们需要保持状态,那么该州必须被移动为该班级的static
成员。
答案 1 :(得分:3)
如果你的编译器支持0x lambda,你可以使用闭包:
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;
}
您的MemoryTester类无需更改,也无需更改库SetAllocateFunction& setFreeFunction属于。
如果没有lambda,而不是a singleton class,请使用单个全局对象:
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);
}
这里的优点是整个MemoryTester类因为一个特殊需要而没有受到限制。您可以根据需要创建更多功能(例如tester_b_malloc / free),以适应同一程序中的其他用途。
答案 2 :(得分:1)
如果您正在使用GCC,那么您可以让链接器使用--wrap选项(或-Wl, - wrap,malloc)为您包装该函数。
然后你可以拦截对malloc的调用,因为对该函数的所有调用都将被重定向到__wrap_malloc。你可以使用名称__real_malloc来调用真实的(原始c-lib)malloc函数,或者你可以替换你自己的替换(如果没有调用__real_malloc,那么链接器可能能够删除原来的c- lib malloc all-together)。
void *__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
FWIW,您可以替换全局的new和delete操作,然后您可以只使用自己的内存系统(即使您使用第三方编译库中的代码,只要它们没有重载全局new和delete) )。
以下是一些很棒的信息:Tutorial of Replacing "new" and "delete"
答案 3 :(得分:0)
如果我理解你的要求,那就没有“约束力”了。一旦分配了内存,就可以告诉编译器用户输入一个类型,在你的情况下是一个reinterpret_cast。例如,在你的分配函数中:
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.
然后你返回你的最终类型。
要知道要使用哪种类型,您肯定希望使用模板。
不要忘记C ++是一种静态类型语言:您不能将函数绑定到对象类型。好的,你可以,但是,你必须使用std :: function或函数指针,这不是你想要的。
答案 4 :(得分:0)
除非您创建全局对象。如果框架采用常规函数指针,那么你就会遇到它提供的内容,如果它没有提供传统的void * userdata样式,那么你就会被填充,或者它是全局对象时间。
答案 5 :(得分:-2)
拥有一个单独的MemoryTester对象,并具有调用该对象的成员函数的桥接静态函数。