防止为嵌入式项目编译malloc / free

时间:2011-08-05 12:21:11

标签: c++ design-patterns embedded stack heap

背景:我们正在使用Keil来编译我们的恩智浦LPC2458项目。 Keil的RealView RTOS上运行着许多任务。创建了堆栈空间,该空间被分配给每个任务。默认情况下没有创建HEAP,我想避免它,因为我们无法负担代码空间开销和“垃圾收集”的成本

目标:在嵌入式代码中使用C ++而不使用堆。 Keil提供了#pragma(__ use_no_heap),它可以防止malloc()和free()调用被链接。

解决方案:我尝试使用私有静态指针创建Singleton。我希望不会调用new()因为我在getDLMData()中将dlmData声明为static。出于某种原因,链接器仍然声明正在调用malloc()和free()。我想到了私有运算符new()和私有运算符delete(),然后在重载函数中将dlmData声明为静态。它由于某种原因不起作用。我做错了什么?

    //class declaration
    class DataLogMaintenanceData
    {
    public:
      static DataLogMaintenanceData* getDLMData();
      ~DataLogMaintenanceData()
      { instanceFlag = FALSE; }
    protected:
      DataLogMaintenaceData(); //constructor declared protected to avoid poly
    private:
      static Boolean instanceFlag;
      static DataLogMaintenceData *DLMData;
    }

    //set these to NULL when the code is first started
    Boolean DataLogMaintenanceData::instanceFlag = FALSE;
    DataLogMaintenanceData *DataLogMaintenaceData::DLMData = NULL;    

    //class functions
    DataLogMaintenanceData *DataLogMaintenanceData::getDLMData()
    {
        if (FALSE == instanceFlag)
        {
            static DataLogMaintenanceData dlmData;
            DLMData = &dlmData;
            instanceFlag = TRUE;
            return DLMData;
        }
        else
        {
            return DLMData;
        }
    }

    void InitDataLog ( void )
    {
        DataLogMaintenanceData *dlmData;
        dlmData = DataLogMaintenanceData::getDLMData();
        // to avoid dlmData warning
        dlmData = dlmData;
    }

    //ACTUAL TASK
    __task DataLog()
    {
      .. .. .. code to initialize stuff

      InitDataLog();

      .. .. ..more stuff
    }

由于某种原因,我可以编译的唯一方法是创建一个堆空间,然后允许将malloc()和free()调用编译到项目中。正如预期的那样,“静态”盟友定义的对象dlmData驻留在分配给dataLog.o模块的RAM空间中(即它不存在于HEAP中)。

我无法弄清楚,我检查了谷歌,我错过了什么?在编译纯对象时,C ++中是否可以绕过malloc()和free()?我知道我可以替换RTOS的malloc()和free()的实现什么都不做,但我想避免编译我不会使用的代码。

3 个答案:

答案 0 :(得分:2)

可能我们没有看到的一些代码调用了一个在幕后调用malloc的函数。

http://www.keil.com/support/man/docs/armlib/armlib_CJAIJCJI.htm,您可以使用链接行上的--verbose --list=out.txt获取有关malloc来电者的详细信息。

答案 1 :(得分:1)

Keil安装中包含一组PDF ...其中一个文档(文档ID DUI0475A)标题为“使用ARM C和C ++库和浮点支持”。它讨论了在几个地方使用堆(以及防止它的使用)。

具体来说,请查看第2.64节“避免ARM提供的堆和堆使用库函数”,其中有很多好的信息。该部分中有趣的文字:

  

您可以参考 __use_no_heap __use_no_heap_region 符号   您的代码,以保证没有链接堆使用函数   ARM库。

     

__use_no_heap 防止使用malloc(),realloc(),free(),   以及使用这些功能的任何功能。例如,calloc()和   其他stdio功能。

     

__use_no_heap_region __ use_no_heap 具有相同的属性,但在   另外,防范使用堆内存区域的其他东西。   例如,如果将main()声明为带参数的函数,则   堆区域用于收集argc和argv。

由于您的问题是如何阻止 malloc() 被调用/使用,这可能会让您走上正确的轨道。

答案 2 :(得分:0)

从您发布的代码中我看不到任何想要在堆上分配内存的内容。在某处发生了隐含的转换吗?如果你在没有这门课的情况下编译怎么办?

你能做什么:

1)在调试器下运行(假设您可以在模拟器上构建可运行的映像),在malloc中设置断点并检查堆栈

2)提供自己的malloc并自由地使链接器满意,然后重复步骤1.

您可能会发现需要链接到不同版本的C运行时启动。在最坏的情况下,如果对malloc / free的调用次数有限,你可以推出自己的版本,这将给调用者一些预先分配的内存 - 但希望这不是必要的。