【问题标题】:Error[Lp001] running out of memory when I shouldn't错误 [Lp001] 内存不足,我不应该这样做
【发布时间】:2015-05-28 18:54:30
【问题描述】:

我目前正在处理一个使用不同语言设置的项目。为了解决这个问题,一个表用于存储程序中使用的不同语言的所有文本。因此,每当要在屏幕上写入文本时,都会调用此表,并根据当前语言设置返回文本字符串。我最近加入了这个项目,我注意到存储它的方式不是很优化,并且对于添加的每种新语言,查找正确字符串所需的时间都会增加。因此,我想出了一个(在我看来)更好的解决方案。但是,当我尝试实现它时,我遇到了一个错误,即使用了太多内存,我不明白为什么。我正在使用 IAR 嵌入式工作台。

伪/c++代码中的原始解决方案:

typedef struct
{
    enum textId;
    enum language;
    string textString;
} Text;

static const Text s_TextMap[] = 
{
     { TextId::RESTORE_DATA_Q                ,Language::ENGLISH        ,"Restore Data?"                          },
     { TextId::RESTORE_DATA_Q                ,Language::SWEDISH        ,"Återställa data?"                       },
     { TextId::RESTORE_DATA_Q                ,Language::GERMAN         ,"Wiederherstellen von Daten?"            },
     { TextId::CHANGE_LANGUAGE               ,Language::ENGLISH        ,"Change Language"                        },
     { TextId::CHANGE_LANGUAGE               ,Language::SWEDISH        ,"Välj språk"                             },
     { TextId::CHANGE_LANGUAGE               ,Language::GERMAN         ,"Sprache wählen"                         },
};

我在伪/c++ 代码中的解决方案:

typedef struct
{
    const char* pEngText;
    const char* pSweText;
    const char* pGerText;
} Texts;

static Texts addTexts(const char* pEngText, const char* pSweText, const char* pGerText)
{
    Texts t;
    t.pEngText = pEngText;
    t.pSweText = pSweText;
    t.pGerText = pGerText;
    return t;
}

typedef struct
{
    enum textId;
    Texts texts;
} Text;

static const TextTest s_TextMapTest[] =
{
     {TextId::RESTORE_DATA_Q,        addTexts("Restore Data?","Återställa data?","Wiederherstellen von Daten?")},
     {TextId::CHANGE_LANGUAGE,        addTexts("Change Language","Välj språk","Sprache wählen")},
};

我的解决方案在一般情况下的查找速度显然更快,并且根据我的计算,它也应该使用更少的内存。当使用完整表时,我计算出原始解决方案需要 7668 个字节,而我的解决方案需要 4248 个字节。我这样做的方法是在一个小测试程序中实现完整的表并使用 sizeof(s_TextMap)。但是,当我尝试编译代码时,出现链接错误:

错误[Lp011]:部分放置失败 无法为 (总未提交空间 0x757eb)中总估计最小大小为 0x130301 字节(最大对齐 0x1000)的部分/块分配空间。

错误[Lp011]:部分放置失败 无法为 中总估计最小大小为 0x47de4 字节(最大对齐 0x20)的部分/块分配空间(总未提交空间 0x1fff1)。

错误[Lp021]:压缩初始化程序批处理“USER_DEFAULT_MEMORY-1”的目标放置在取决于批处理大小的地址,使用 lz77 压缩时不允许这样做。考虑改用“使用packing = zeros 复制初始化”(或无)。

错误[Lp021]:压缩初始化程序批处理“USER_DEFAULT_MEMORY-1”的目标放置在取决于批处理大小的地址,使用 lz77 压缩时不允许这样做。考虑改用“使用包装=零进行复制初始化”(或无)。

我最困惑的错误是第一个错误,它指出我的代码估计占用 0x130301 字节的内存,我认为这是不可能的。这可能是 IAR 中的一些错误还是我遗漏了什么?

【问题讨论】:

    标签: c++ memory arm embedded iar


    【解决方案1】:

    好的,所以我设法让它工作。我删除了额外的结构和函数,并将其简化为:

    typedef struct
    {
        TextId::e textId;
        const char* pEngText;
        const char* pSweText;
        const char* pGerText;
        const char* pFinText;
    } Text;
    

    对我来说它看起来不太好,但至少它有效

    【讨论】:

      【解决方案2】:

      在您的解决方案中,s_TextMapTest[] 必然位于 RAM 而不是 ROM 中,因为指针是在运行时设置的 - 尽管尚不清楚您是如何设法将函数调用用作数组元素初始化程序。在大多数微控制器上,RAM 是一种更为有限的资源。您没有提供有关目标或其内存映射的信息。

      无论哪种方式,您都应该检查链接器的内存映射输出,以验证数据的位置是否正确以及您期望的位置。

      您在自己的答案中提出的原始代码和解决方案是 ROMable。

      在保持 ROMable 的同时保持原始提案形式的解决方案是将 addTexts() 编写为宏而不是函数:

      #define addTexts( eng, swe, ger, fin ) {eng, swe, ger, fin}
      

      虽然我看不出有什么优势,而且您并不是真正“添加”文本 - 初始化时文本始终存在。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 2015-09-20
        • 1970-01-01
        相关资源
        最近更新 更多