C++ 如何静态识别动态堆分配?

C++ 如何静态识别动态堆分配?,c++,embedded,heap,heap-memory,C++,Embedded,Heap,Heap Memory,我即将在我的应用程序中删除“尽可能多”的动态堆分配,我想知道如何确保我没有遗漏任何东西 目前,我正在寻找一种方法来轻松甚至自动判断代码中是否有任何(或哪些)部分可能调用new/delete或malloc/free的标准实现,而无需动态跟踪分配(即通过静态代码分析或来自编译器/链接器的反馈) 很容易发现(或搜索)直接调用new或malloc的代码当然: int main() { auto s = new std::string(); delete s; } 为了防止分配被隐藏在第三方库中

我即将在我的应用程序中删除“尽可能多”的动态堆分配,我想知道如何确保我没有遗漏任何东西

目前,我正在寻找一种方法来轻松甚至自动判断代码中是否有任何(或哪些)部分可能调用
new
/
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 ";
    }
}
这种方法适用于小型二进制文件,在小型二进制文件中,您可以管理零堆分配,但只要您希望允许某些分配(例如,在只执行一次的代码中,或者在错误情况下,就很难将可能分配堆内存的代码与不分配堆内存的代码分开)

在目前最好的情况下,我可以想象编译器或静态代码分析器为我提供了源代码中可能导致动态堆分配的位置列表。这个列表我可以定期检查/筛选设置中正常的情况(例如引导代码或错误处理)和需要重构的情况(例如,通过提供特殊分配器)

您的方法、工具和经验是什么?

一种策略可能是使用您自己的函数调用malloc/calloc,该函数决定是否允许调用,如果不允许,则断言(或日志)。可以通过检查您在初始化期间设置/清除的全局标志、错误处理程序等来做出决定


当然,这不是静态的,但它可以作为清理代码的良好起点。

您确实需要以某种方式限制问题。在第三方库中查找动态内存分配的使用是一项艰巨的任务,请给出实现选择的范围,以及库在您控制之外更新的可能性。Ge一般来说,从头开始设计程序以避免动态内存分配(或者,至少,将使用限制在某些特定代码上)更容易而不是在一个非平凡的现有程序中找到实例并将其删除。这是一个痛苦的发现。我过去所做的是从链接器文件中彻底消除
.heap
段。如果在链接器阶段之后有什么东西尖叫,则某些库中有一些隐藏的堆代码。长期的解决方案是移植到C,因为它更适合于嵌入式编程。
g++ -static-libgcc -static-libstdc++ main.cpp
nm a.out | grep -E "_Znwm|_Znam|_Znwj|_Znaj|_ZdlPv|_ZdaPv|malloc|free"
0000000000471fd0 T __cxa_free_dependent_exception
0000000000471f30 T __cxa_free_exception
                 U free@@GLIBC_2.2.5
                 U __freelocale@@GLIBC_2.2.5
                 U malloc@@GLIBC_2.2.5
0000000000471b20 T _ZdlPv
0000000000491bf0 T _ZdlPvm
0000000000471bc0 t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.2
0000000000402a20 t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.2.cold.5
0000000000471e80 T _ZN9__gnu_cxx9__freeresEv
0000000000472240 T _Znwm
0000000000491c00 T _ZnwmRKSt9nothrow_t
0000000000403f37 t _ZnwmRKSt9nothrow_t.cold.0