Prevent std :: function function in gcc from memory allocation or threshold increase

Is there a way to prevent std::function in gcc from dynamically allocating memory for larger function objects?

I would expect the following code to work without dynamic allocation:

 #include <functional> #include <iostream> // replace operator new and delete to log allocations void* operator new (std::size_t n) { std::cout << "Allocating " << n << " bytes" << std::endl; return malloc(n); } void operator delete(void* p) throw() { free(p); } class TestPlate { private: int value; public: int getValue(){ return value; } void setValue(int newValue) { value = newValue; } int doStuff(const std::function<int()>& stuff) { return stuff(); } }; int main() { TestPlate testor; testor.setValue(15); const std::function<int()>& func = std::bind(&TestPlate::getValue, &testor); std::cout << testor.doStuff(func) << std::endl; testor.setValue(25); std::cout << testor.doStuff(func) << std::endl; } 

However, it allocates 24 bytes. As far as I can tell, this is because a pointer to a method requires 16 bytes, and a pointer to an instance of the class requires another 8 bytes. It seems that A is larger than the internal memory available to the function object, or B is a simple mistake.

I was wondering if there is a way around this type of behavior without changing the signature of std::function or creating a lot of extra shell code.

+6
source share
2 answers

Unfortunately, the GCC function has only room for a pointer to a member function stored internally, so the result of your binding expression is not suitable.

You can use a lambda expression instead:

 std::function<int()> f = [&]{ return testor.getValue(); }; 

This only requires space for the closure type containing a reference to testor (which is half the size of the pointer to the element and one third the size of the binding result), and GCC defines this closure so that it can be stored in std::function .

+6
source

Looking through the libstdC ++ exclusively devious functional header (the default C ++ library for GCC), I found that it is actually impossible to avoid heap allocation with its current implementation. It seems to have a special manager and invoker member that is dedicated to the heap, and requires the class to work. If you really want to look at the source, here you go , but there certainly is black art and witchcraft.

There is some functionality in the header that involves switching to custom allocators , but currently they don't seem to be implemented.

At the same time, you can try Boost.function .

0
source

All Articles