考虑安全软件,一般不允许动态分配,不允许例外。仅当class explicity定义operator new
和delete
时才允许动态分配。对其他类使用运算符new
会导致编译失败。
在描述的情况下导致编译失败的最简单方法是删除全局新运算符:
void* operator new(std::size_t) = delete;
一方面,这会导致标准库的副作用。例如,<array>
包括<new_allocator>
将<stdexcept>
传播到<new_allocator>
。 ::new
使用<array>
运算符,即使您不想使用异常和内存分配,这也会导致构建失败。根据Scoot Meyers src/main.cpp:91:31: error: deleted definition of 'void* operator new(std::size_t)'
void* operator new(std::size_t) = delete; ^
<built-in>: note: previous declaration of 'void* operator new(std::size_t)'
应该是裸金属友好的。
另一方面,这会导致编译器内置运算符错误
::new
是否有任何解决方案禁止<array>
并使用::new
?
是否有任何解决方案可以全局禁止Gemfile
?
答案 0 :(得分:4)
如果您使用GCC和GNU LD,那么我认为您只需将--wrap=malloc
添加到链接器标志即可。由于全局::new
在内部使用malloc()
,因此应用程序中对malloc()
的所有调用都将替换为__wrap_malloc()
。如果此函数未定义,则链接将失败。
另一个可能更简单的选择是将ASSERT(DEFINED(malloc) == 0, "Dynamic allocation used!");
添加到链接描述文件中。这将断言malloc()
未定义。
这两个选项都不会保护您重新定义全局::new
以使用其他形式的全局分配。您可以在链接描述文件中为全局符号::new
执行相同的操作,但它的名称会被修改(在此处为_Znwj
),所以这会有点奇怪......
答案 1 :(得分:3)
无论您使用何种编程语言:
在任何声音,裸机系统上,您只需完全从链接描述文件中删除.heap
段。依赖于动态分配的任何代码都将无法链接。并且您不必为您无法使用的段分配RAM。
答案 2 :(得分:2)
我想强调两件事:
std::string
(即std::basic_string<char, ...>
)或std::streambuf
(即std::basic_streambuf<char, ...>
),以及当您在代码,编译器不会尝试实例化模板,它只是重用预编译版本。为了更好地控制代码,我强烈建议使用带有G ++编译器的-nostdlib
编译选项完全排除标准库。它不会阻止您使用各种模板类,例如来自STL的std::array
,它将为您排除整个C ++库和运行时。
我还建议阅读Practical Guide to Bare Metal C++。它可能会对C ++裸机内部提供更深入的了解。