0

我正在将类型从 C 风格的结构转换为 C++ 风格的结构;我正在添加一个成员,它将强制类型需要一个构造函数,因此我必须从mallocand切换freenewand delete。我可以通过查找sizeof(TYPE).

有什么方法可以找到传递该类型指针的所有实例free?我意识到这一点,因为它的论点并free不能void*保证我在任何地方都发现了该类型被释放。

例如,我是否可以free以某种方式重载,以便在任何地方free(TYPE*)调用编译错误,但在其他任何地方都没有?

4

3 回答 3

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是 to my::free,因此代码无法编译。显然这不会捕获free((void*)ptr);,因为free使用参数以外my::TYPE*的参数调用不受影响。

正如我所写,不需要对free内部命名空间my或具有using namespace my;. 因此,您可能希望为此目的使用新发明的命名空间。或者写一个不那么全面的模板,我即兴创作的。

它也没有捕捉到对std::free. 重载(或命名空间 std 中的任何内容)是未定义的行为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); 
    };
}
于 2013-01-25T12:47:12.137 回答
0

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

当您错误地分配了free'danew()对象时,Valgrind 会告诉您。

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

另一种选择是使用静态分析器,例如 Coverity 或 clang-analyze。

于 2013-01-25T12:08:13.703 回答
0

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

于 2013-01-25T12:13:06.800 回答