静态映射超出堆栈

static map exceeds stack

本文关键字:堆栈 映射 静态      更新时间:2023-10-16

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

由于我不需要在运行时对此查找进行任何更改,因此我想将其声明为静态和常量,并将所有值手动放入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 字节,因为构造函数首先将所有这些条目放在堆栈上,然后再进一步处理它们。

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

我认为 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 实现版本以使用完美的转发:

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));