静态地图超出堆栈

时间:2018-05-25 21:14:32

标签: c++ constructor

情况是我编写了一个汇编程序,我使用std::unordered_multimap容器来存储所有不同的指令,其中实际的助记符是我的密钥到地图中关联的值是一个自定义结构,其中包含一些关于参数的附加信息等。

由于我不需要在运行时对此查找进行任何更改,我认为我将其声明为static和const,并将所有值手动放在initializer_list中。

总之它看起来像这样:

typedef std::wstring STRING;

static const
std::unordered_multimap<STRING, ASM_INSTRUCTION> InstructionLookup = {
//  { MNEMONIC, { Opcode1, Opcode2, Param1Type, Param2Type, Param3Type, NrBytes, Bt1, Bt2, Bt3, Bt4, NoRexW, InvalidIn64Bit, InvalidIn32Bit } },
    { L"AAA",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false } },

    { L"AAD",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 2, 0xD5, 0x0A, 0x00, 0x00, false, true, false } },
    { L"AAD",{ ot_ib, ot_none, par_imm8, par_noparam, par_noparam, 1, 0xD5, 0x00, 0x00, 0x00, false, true, false } },

    { L"AAM",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 2, 0xD4, 0x0A, 0x00, 0x00, false, true, false } },
    ...

我现在的问题是,已经实施了很多指令(目前有1,225个) 因此,当我使用Visual Studio运行代码分析时,它告诉我构造函数超过了98,000 / 16,384字节的堆栈,因为构造函数首先将所有这些条目放在堆栈上,然后再进行处理。

我现在的问题是如何直接在堆上初始化所有空间,最好不必重写它。

1 个答案:

答案 0 :(得分:1)

我认为emplace正是您所寻找的:

InstructionLookup.emplace(std::piecewise_construct, std::forward_as_tuple(L"sXs"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false));

我尝试尽可能地保留您的语法,并将Boost.Assign实现版本从here更改为使用完美转发:

template <typename T, typename U>
class create_unmap
{
private:
    std::unordered_multimap<T, U> m_map;
public:

    template <typename ...Args>
    create_unmap(Args&&... _Val)
    {
        m_map.emplace(std::forward<Args>(_Val)...);
    }

    template <typename ...Args>
    create_unmap<T, U>& operator()(Args&&... _Val)
    {
        m_map.emplace(std::forward<Args>(_Val)...);
        return *this;
    }

    operator std::unordered_multimap<T, U>()
    {
        return std::move(m_map);
    }
};

您可以使用以下语法声明地图:

static const std::unordered_multimap<STRING, ASM_INSTRUCTION> InstructionLookupt = create_unmap<STRING, ASM_INSTRUCTION>
        (std::piecewise_construct, std::forward_as_tuple(L"AAA"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false))
        (std::piecewise_construct, std::forward_as_tuple(L"AAD"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false))
        (std::piecewise_construct, std::forward_as_tuple(L"AAD"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false));