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

时间:2013-01-25 12:04:41

标签: c++ visual-c++

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

有什么方法可以找到将该类型的指针传递给free的所有实例?我意识到,因为free的论证是void*,这不是我在任何地方找到的类型的保证。

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

3 个答案:

答案 0 :(得分:6)

  

我可以以某种方式超载吗

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

#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);,因为使用free以外的参数调用my::TYPE*不会受到影响。

正如我所写,不需要在free内部myusing namespace my;的代码中调用std::free。因此,您可能希望使用新发明的命名空间。或者写一个不那么全面的模板,我即兴创作了一个。

它也无法捕获对std::free的完全限定的呼叫。重载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); }; } (或命名空间std中的任何内容)是未定义的行为,但如果有必要,您可能只是为了查找调用站点而逃脱它。像这样:

{{1}}

答案 1 :(得分:0)

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

Valgrind会在您错误地free分配new()分配的对象时告诉您。

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

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

答案 2 :(得分:0)

您无法直接执行此操作...但是,您可以使用技巧来查找使用此类(错误初始化的)实例的所有位置。只需将前结构的所有成员 - 现在的类 - 私有。无论何时使用这些字段/成员,编译器都会引发错误。这将为您提供进一步分析代码并消除所有malloc /免费调用的起点。