C++ 将实例成员方法用作函数指针时堆损坏?
问题:在传递实例成员函数时,是否需要特别的预防措施 场景:当我传递并调用实例成员函数时,偶发崩溃C++ 将实例成员方法用作函数指针时堆损坏?,c++,visual-c++,C++,Visual C++,问题:在传递实例成员函数时,是否需要特别的预防措施 场景:当我传递并调用实例成员函数时,偶发崩溃 通过函数指针不断调用成员函数(数十万次) 进程最终崩溃,但堆栈跟踪有点不一致。唯一的共同点似乎是new/malloc失败,尽管有大量可用的进程内存 就我所知,该实例(下面示例中的类)仍然是活动的 成员函数可以有一个空的主体;只是尝试调用该方法 通过函数指针足以损坏堆(假设是堆损坏) 单线程,单进程 这是XP上的visual studio 6.0 注意:为了回避这个问题,我让CFunctor成为类的朋
class CFunctor
{
private:
typedef void (CClass::*Calculator)(args);
CClass *c;
Calculator func;
public:
CFunctor(CClass* c, Calculator func)
{
this->c = c;
this->func = func;
};
~CFunctor()
{
this->c = NULL;
this->func = NULL;
}
virtual void calculate(args)
{
(c->*func)(args);
}
};
class CFunctorConsumer
{
public:
CFunctorConsumer(CFunctor *functor)
{
this->functor = functor;
}
~CFunctorConsumer()
{
this->functor = NULL;
}
virtual void DoStuff(args)
{
if (this->functor)
{
this->functor->calculate(args);
}
}
private:
CFunctor *functor;
}
class CClass
{
private:
CFunctorConsumer* testFunctor;
void CalculationMethod(args)
{
// This method can be empty, and still crashes
}
public:
CClass()
{
this->testFunctor = new CFunctorConsumer(new CFunctor(this, this->CalculationMethod));
}
void Test()
{
this->testFunctor->DoStuff( args );
}
}
我在这里看到了两个
CFunctor
构造函数,其中一个应该是析构函数,但前面没有tilde
方法
CFunctor::calculate
声明为虚拟,因此您可能使用某个派生类MyFunctor
,而不是CFunctor
本身?您可能忘记了将适当的数据从MyFunctor
构造函数传递给基类CFunctor
构造函数。默认构造函数将基成员初始化为NULL,这会导致计算(args)
中的内存访问错误您提到内存问题,并且在示例中,您为类提供了分配内存而从不销毁内存的方法
您似乎正在为析构函数中的成员分配NULL。这是没有用的。在C++中,用<代码>删除> /COD>重新分配你的代码>新< /代码>,或者在可能的时候使用智能指针。赋值为NULL只会更改指针,但不会释放任何内容
另外,如果您有非默认的复制构造函数/析构函数/复制赋值,则最有可能是。修复了该示例。默认构造函数实际上是一个析构函数。对于释放和免费析构函数代码来说,这已经足够公平了。因此,如果我正确地管理实例生命周期(即,我自己的代码中没有bug),那么传递实例成员函数并调用它本身就没有什么不安全的地方吗?我很久很久没有接触过C/C++了。你试过在调试器中运行它吗?它应该告诉你程序停止的地方。如果您不确定类对象是否存在/一致性,请添加析构函数并在其中设置陷阱(调试器的断点或一些代码来重置类对象的全局标志/计数器)。您还可以在对象的开头添加一些成员,并使用特定模式对其进行初始化,然后将其签入
CalculationMethod
。这并不能阻止撞车,但可以提供撞车原因的线索。。。