背景:我们正在使用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()的实现什么都不做,但我想避免编译我不会使用的代码。
答案 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的调用次数有限,你可以推出自己的版本,这将给调用者一些预先分配的内存 - 但希望这不是必要的。