查找在给定指针类型上调用 free 的位置

Find where free is called on a given pointer type

本文关键字:调用 free 位置 类型 定指 指针 查找      更新时间:2023-10-16

我正在将类型从 C 样式结构转换为 C++ 样式结构;我正在添加一个成员,它将强制该类型需要一个构造函数,因此我必须从mallocfree切换到newdelete。我可以通过查找sizeof(TYPE)找到分配类型的任何地方(由于此代码库的约定)。

有什么方法可以找到将该类型的指针传递给free的所有实例?我意识到,由于对free的论据是void*这并不能保证我在任何地方都发现该类型被释放。

例如,我可以以某种方式重载free,以便在调用free(TYPE*)任何地方都会遇到编译错误,而不是在其他任何地方?

我可以以某种方式免费过载吗

你当然可以试一试。例如:

#include <cstdlib>
#include <iterator>
namespace my {
    class TYPE { };
    template <typename T>
    void free(T *ptr) { std::iterator_traits<T>::attempt_to_free_TYPE; }
}
using std::malloc;
using std::free;
using my::TYPE;
int main() {
    TYPE *ptr = (TYPE *) malloc(sizeof(TYPE));
    free(ptr);
}

多亏了ADL,对free的调用是my::free,因此代码无法编译。显然这不会引起free((void*)ptr);,因为使用my::TYPE*以外的参数调用free不受影响。

正如我所写的,不需要在命名空间my或具有using namespace my;的代码中调用任何调用free。因此,您可能希望使用新发明的命名空间来实现此目的。或者写一个不那么包罗万象的模板,我即兴创作了那个。

它也不会捕获对std::free的完全限定调用。重载std::free(或命名空间 std 中的任何内容)是未定义的行为,但如果有必要,您可能只是为了查找调用站点而侥幸逃脱。像这样:

template <typename T>
struct allowed_to_free {
    enum { value };
};
template <>
struct allowed_to_free<TYPE> {};
namespace std {
    template <typename T>
    void free(T *ptr) {
        allowed_to_free<T>::value; 
        free((void*)ptr); 
    };
}
使用 valgrind

:如果您愿意在运行时进行签入,请考虑使用 valgrind 来执行此类任务。

Valgrind 会告诉您何时错误地freenew()分配的对象。

由于OP不在Linux中,而是在VS中,我想有类似于valgrind的工具。

另一种选择是使用静态分析器,例如覆盖率或 clang-analysis。

你不能直接做...但是,您可以提取一个技巧来查找使用此类(错误初始化)实例的所有位置。只需将以前的结构(现在是类)的所有成员设为私有即可。无论在哪里使用这些字段/成员,编译器都会引发错误。这将为您提供一个起点,以进一步分析代码并清除任何恶意/免费调用。