防止为嵌入式项目编译 malloc/free
背景:我们正在使用 Keil 编译 NXP LPC2458 项目。 Keil 的 RealView RTOS 上运行着许多任务。创建了堆栈空间,并将其分配给每个任务。默认情况下没有创建堆,我想避免它,因为我们无法承担代码空间开销和“垃圾收集”的成本
目标:在嵌入式代码中使用 C++,而不使用堆。 Keil 提供了 #pragma (__use_no_heap),它可以防止链接 malloc() 和 free() 调用。
解决方案:我尝试使用私有静态指针创建单例。我希望 new() 不会被调用,因为我在 getDLMData() 中将 dlmData 声明为静态。由于某种原因,链接器仍然声明正在调用 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() 实现而不执行任何操作,但我想避免编译我不会使用的代码。
Background: We are using Keil to compile our NXP LPC2458 project. There are numerous tasks that are being run on Keil’s RealView RTOS. There is stack space created, which is being allocated to each task. There is no HEAP created by default, and I want to avoid it since we can't afford the code-space overhead and the cost of "garbage collecting"
Objective: Use C++ in the embedded code without using the heap. Keil provides the #pragma (__use_no_heap) which prevents malloc() and free() calls to be linked.
Solution: I tried creating a Singleton with a private static pointer. My hopes were that the new() would not be called since I declared dlmData as static in the getDLMData(). For some reason, the linker still states that malloc() and free() are being called. I have thoughts of a private operator new () and a private operator delete() , and then declaring the dlmData as static within the overloaded function. It is not working for some reason. WHAT AM I DOING WRONG?
//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
}
For some reason, the only way I can get this to compile, is to create a heap space and then allow the malloc() and free() calls to be compiled into the project. As expected, the “static”ally defined object, dlmData, resides in the RAM space allocated to the dataLog.o module (i.e. it doesn’t live in the HEAP).
I can’t figure out, and I have checked Google, what am I missing? Is it possible in C++ to bypass malloc() and free() when compiling pure objects? I know I can replace the RTOS’s implementation of malloc() and free() to do nothing, but I want to avoid compiling in code that I won’t use.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可能我们没有看到的一些代码调用了一个在幕后调用
malloc
的函数。来自 http://www.keil.com/support/man/docs/ armlib/armlib_CJAIJCJI.htm 您可以在链接行上使用
--verbose --list=out.txt
来获取有关malloc
的详细信息来电者。Probably some of the code we aren't seeing calls a function that calls
malloc
behind the scenes.From http://www.keil.com/support/man/docs/armlib/armlib_CJAIJCJI.htm you can use
--verbose --list=out.txt
on the link line to get details about themalloc
caller.Keil 安装中包含一组 PDF...其中一个文档(文档 ID DUI0475A)的标题为“使用 ARM C 和 C++ 库以及浮点支持”。它在几个地方讨论了堆的使用(以及阻止其使用)。
具体来说,请查看第 2.64 节“避免使用 ARM 提供的堆和使用堆的库函数”,那里有很多有用的信息。该部分中有趣的文字:
由于您的问题是关于如何防止
malloc()
被调用/使用,这可能会让您走上正确的轨道。Included in the Keil installation is a set of PDFs... one of the documents (document ID DUI0475A) is titled "Using ARM C and C++ Libraries and Floating-Point Support". It discusses use of the heap (and preventing its use) in several places.
Specifically, check out section 2.64 "Avoiding the ARM-supplied heap and heap-using library functions", lots of good information there. The interesting text in that section:
Since your question is about how prevent
malloc()
from being called / used, that might put you on the right track.从您发布的代码中,我看不到任何想要在堆上分配内存的内容。某处是否发生了隐式转换?如果你编译时根本没有这个类怎么办?
你可以做什么:
1)在调试器下运行(假设你可以构建一个可运行的图像,也许在模拟器上),在malloc中设置断点并检查堆栈
2)提供你自己的malloc和free以使链接器满意,然后重复步骤1.
您可能会发现需要链接不同版本的 C 运行时启动。在最坏的情况下,如果对 malloc/free 的调用次数受到限制,您可以推出自己的版本,这将为调用者提供一些预分配的内存 - 但希望这不是必需的。
From the code you've posted I cannot see anything that would like to allocate the memory on the heap. Are there any implicit conversions taking place somewhere? What if you compile without this class at all?
What you could do:
1) Run under debugger (assuming you can build a runnable image, maybe on an emulator), set a breakpoint in malloc and examine the stack
2) Provide your own malloc and free to make linker happy, then repeat step 1.
You may find that you need to link against a different version of C runtime startup. In the worst case if number of calls to malloc/free is limited you can roll out your own version which will give the callers some preallocated memory - but hopefully this will not be neccessary.