基本上取决于您的编译器和内存量。如果RAM超过几KB,则动态内存分配可以大大帮助。如果您使用的标准库中malloc的实现未针对您的内存大小进行调整,则可以编写自己的实现,或者有很好的示例,例如
mm_malloc from Ralph Hempel,您可以使用它来编写新的和删除运算符。
我不同意那些重复异常和stl容器太慢或太臃肿等传言的人。当然,它比简单的C malloc添加了一些代码,但是明智地使用异常可以使代码更加清晰,并避免在C中进行太多的错误检查。
必须记住,STL分配器将以2的幂增加其分配,这意味着有时它会进行一些重新分配,直到达到正确的大小,如果您知道要分配的大小,则可以使用
reserve来防止这种情况,因此它变得与所需大小的一个malloc一样便宜。
如果你在一个向量中有一个大的缓冲区,例如,在某个时刻它可能会重新分配并在重新分配和移动数据时使用了1.5倍于你打算使用的内存大小。(例如,在某个时刻,它分配了N个字节,你通过追加或插入迭代器添加数据,它会分配2N个字节,复制前N个字节并释放N个字节。在某个时刻,你分配了3N个字节)。
所以最终它有很多优点,并且只有当你知道自己在做什么时才能付出。你应该知道一些C++的工作原理,以便在嵌入式项目中使用它而不会出现意外情况。
对于那些使用固定缓冲区和重置的人,如果内存不足,你可以在new运算符或其他地方进行重置,但这意味着你设计得不好,可能会耗尽你的内存。
在ARM RealView 3.1中抛出异常:
--- OSD\#1504 throw fapi_error("OSDHANDLER_BitBlitFill",res)
S:218E72F0 E1A00000 MOV r0,r0
S:218E72F4 E58D0004 STR r0,[sp,#4]
S:218E72F8 E1A02000 MOV r2,r0
S:218E72FC E24F109C ADR r1,{pc}-0x94
S:218E7300 E28D0010 ADD r0,sp,#0x10
S:218E7304 FA0621E3 BLX _ZNSsC1EPKcRKSaIcE <0x21a6fa98>
S:218E7308 E1A0B000 MOV r11,r0
S:218E730C E1A0200A MOV r2,r10
S:218E7310 E1A01000 MOV r1,r0
S:218E7314 E28D0014 ADD r0,sp,#0x14
S:218E7318 EB05C35F BL fapi_error::fapi_error <0x21a5809c>
S:218E731C E3A00008 MOV r0,#8
S:218E7320 FA056C58 BLX __cxa_allocate_exception <0x21a42488>
S:218E7324 E58D0008 STR r0,[sp,#8]
S:218E7328 E28D1014 ADD r1,sp,#0x14
S:218E732C EB05C340 BL _ZN10fapi_errorC1ERKS_ <0x21a58034>
S:218E7330 E58D0008 STR r0,[sp,#8]
S:218E7334 E28D0014 ADD r0,sp,#0x14
S:218E7338 EB05C36E BL _ZN10fapi_errorD1Ev <0x21a580f8>
S:218E733C E51F2F98 LDR r2,0x218e63ac <OSD\#1126>
S:218E7340 E51F1F98 LDR r1,0x218e63b0 <OSD\#1126>
S:218E7344 E59D0008 LDR r0,[sp,#8]
S:218E7348 FB056D05 BLX __cxa_throw <0x21a42766>
看起来并不可怕,如果异常没有被抛出,在 {} 块或函数内部不会增加额外的开销。