我将在应用程序中删除“尽可能多的”动态堆分配,我想知道如何确保自己没有错过任何事情。
当前,我正在寻找一种方法来轻松甚至自动判断代码的任何部分(或哪些部分)可能调用and( ).addFilterAfter( revokeFilterBean(), OAuth2AuthenticationProcessingFilter.class )
/ new
或{{1}的标准实现} / delete
,而不必动态跟踪分配(即通过静态代码分析或来自编译器/链接器的反馈)。
很容易发现(或搜索)直接调用malloc
或free
的代码:
new
只要分配隐藏在第三方库的深处或不太明显的情况下(例如malloc
),我仍然可以在二进制文件中搜索新的/删除的错误符号:
int main() {
auto s = new std::string();
delete s;
}
但是这种方法只能找到throw
的直接使用。如果我的代码(或第三方的东西)使用了标准库,则仅通过调用g++ main.cpp
nm a.out | grep -E "_Znwm|_Znam|_Znwj|_Znaj|_ZdlPv|_ZdaPv|malloc|free"
U _ZdlPvm@@CXXABI_1.3.9
U _Znwm@@GLIBCXX_3.4
就不会检测到它:
new/delete/malloc/free
我当前的方法是链接到静态标准库(nm
/ int main() {
std::string a;
for(int i = 0; i < 100; ++i) {
a += "data ";
}
}
),并查看是否完全引用了-static-libgcc
/ -static-libstdc++
< / em>在整个二进制文件中:
new
这种方法适用于小型二进制文件,您可以在其中分配零堆分配,但是只要您想允许 some 分配(例如,在仅执行代码中)一次或在错误的情况下,因此很难分离可能分配堆内存的代码和可能不分配堆内存的代码。
在最佳情况下,我目前可以想象编译器或静态代码分析器为我提供了源代码中的位置列表,这些位置可能会导致动态堆分配。我可以定期检查/过滤此列表,以确认设置中可以通过的情况(例如引导程序代码或错误处理)以及需要重构的情况(例如通过提供特殊的分配器)。
您的方法,工具和经验是什么?
答案 0 :(得分:0)
一种策略可能是使用您自己的函数wrap对malloc / calloc的调用,该函数确定是否允许它们,如果不允许则断言(或记录)。可以通过检查在初始化,错误处理程序等过程中设置/清除的全局标志来做出决定。
这当然不是静态的,但是它可以作为清理代码的一个很好的起点。