避免使用std :: function和member function进行内存分配 [英] Avoid memory allocation with std::function and member function

查看:217
本文介绍了避免使用std :: function和member function进行内存分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码仅用于说明问题.

This code is just for illustrating the question.

#include <functional>
struct MyCallBack {
    void Fire() {
    }
};

int main()
{
    MyCallBack cb;
    std::function<void(void)> func = std::bind(&MyCallBack::Fire, &cb);
}

使用valgrind进行的实验表明,分配给func的行在Linux上使用gcc 7.1.1动态分配了大约24个字节.

Experiments with valgrind shows that the line assigning to func dynamically allocates about 24 bytes with gcc 7.1.1 on linux.

在真实的代码中,我有几个不同的结构,所有这些结构都带有void(void)成员函数,该成员函数存储在大约1000万个std::function<void(void)>中.

In the real code, I have a few handfuls of different structs all with a void(void) member function that gets stored in ~10 million std::function<void(void)>.

有什么办法可以避免在执行std::function<void(void)> func = std::bind(&MyCallBack::Fire, &cb);时动态分配内存吗? (或者将这些成员函数分配给std::function)

Is there any way I can avoid memory being dynamically allocated when doing std::function<void(void)> func = std::bind(&MyCallBack::Fire, &cb); ? (Or otherwise assigning these member function to a std::function)

推荐答案

不幸的是,std::function的分配器已在C ++ 17中删除.

Unfortunately, allocators for std::function has been dropped in C++17.

现在,避免在std::function内部进行动态分配的公认解决方案是使用lambda而不是std::bind.这样做确实有效,至少在GCC中是这样-它有足够的静态空间来存储lambda(在您的情况下),但没有足够的空间来存储活页夹对象.

Now the accepted solution to avoid dynamic allocations inside std::function is to use lambdas instead of std::bind. That does work, at least in GCC - it has enough static space to store the lambda in your case, but not enough space to store the binder object.

std::function<void()> func = [&cb]{ cb.Fire(); };
    // sizeof lambda is sizeof(MyCallBack*), which is small enough

作为一般规则,对于大多数实现,以及仅捕获单个指针(或引用)的lambda,使用这种技术可以避免在std::function内部进行动态分配(通常,更好的方法是作为其他答案建议).

As a general rule, with most implementations, and with a lambda which captures only a single pointer (or a reference), you will avoid dynamic allocations inside std::function with this technique (it is also generally better approach as other answer suggests).

请记住,要使其正常工作,您需要确保此lambda会比std::function寿命长.显然,这并非总是可能的,有时您必须通过(大)副本捕获状态.如果发生这种情况,除了您自己修改STL(显然,一般情况下不建议这样做,但可以在某些特定情况下完成)之外,目前没有任何方法可以消除函数中的动态分配.

Keep in mind, for that to work you need guarantee that this lambda will outlive the std::function. Obviously, it is not always possible, and sometime you have to capture state by (large) copy. If that happens, there is no way currently to eliminate dynamic allocations in functions, other than tinker with STL yourself (obviously, not recommended in general case, but could be done in some specific cases).

这篇关于避免使用std :: function和member function进行内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆