阻止gcc中的std::function分配内存或增加阈值
Prevent std::function in gcc from allocating memory or increase threshhold
有什么方法可以防止 gcc 中的 std::function
为较大的函数对象动态分配内存吗?
我原以为下面的代码可以在没有动态分配的情况下工作:
#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;
}
但是它分配了 24 个字节。据我所知,这是因为指向方法的指针需要 16 个字节,而指向 class 实例的指针需要另外 8 个字节。这似乎是 A 大于函数对象可用的内部内存,或者 B 是一个普通的错误。
我想知道是否有任何方法可以在不更改 std::function
的签名或创建大量额外包装代码的情况下规避此类行为。
查看异常skin-crawling functional
header of libstdc++(GCC默认的C++库),我发现实际上不可能用它来避免堆分配目前的实施。它似乎有一个特殊的管理器和调用者成员 heap-allocated,class 需要它才能工作。如果你真的想看看来源,here you go,但那里肯定有黑魔法和巫术。
header 中的某些功能暗示传入 custom allocators 已计划,但目前似乎尚未实现。
在此期间,您可以尝试 Boost.function。
不幸的是,GCC 的 function
只有 space 用于指向内部存储的成员函数的指针,因此绑定表达式的结果不适合。
您可以改用 lambda 表达式:
std::function<int()> f = [&]{ return testor.getValue(); };
对于包含对 testor
的引用的闭包类型,这只需要 space(这是成员指针大小的一半,绑定结果大小的三分之一), GCC 定义了闭包,因此它可以存储在 std::function
.
中
有什么方法可以防止 gcc 中的 std::function
为较大的函数对象动态分配内存吗?
我原以为下面的代码可以在没有动态分配的情况下工作:
#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;
}
但是它分配了 24 个字节。据我所知,这是因为指向方法的指针需要 16 个字节,而指向 class 实例的指针需要另外 8 个字节。这似乎是 A 大于函数对象可用的内部内存,或者 B 是一个普通的错误。
我想知道是否有任何方法可以在不更改 std::function
的签名或创建大量额外包装代码的情况下规避此类行为。
查看异常skin-crawling functional
header of libstdc++(GCC默认的C++库),我发现实际上不可能用它来避免堆分配目前的实施。它似乎有一个特殊的管理器和调用者成员 heap-allocated,class 需要它才能工作。如果你真的想看看来源,here you go,但那里肯定有黑魔法和巫术。
header 中的某些功能暗示传入 custom allocators 已计划,但目前似乎尚未实现。
在此期间,您可以尝试 Boost.function。
不幸的是,GCC 的 function
只有 space 用于指向内部存储的成员函数的指针,因此绑定表达式的结果不适合。
您可以改用 lambda 表达式:
std::function<int()> f = [&]{ return testor.getValue(); };
对于包含对 testor
的引用的闭包类型,这只需要 space(这是成员指针大小的一半,绑定结果大小的三分之一), GCC 定义了闭包,因此它可以存储在 std::function
.