Visual Studio watch 显示同一对象的不同值

Visual Studio watch shows different values for same object

我正在和其他几个学生一起开发游戏,我刚刚遇到了一个问题。 我有一个工厂对象,它有一个名为 registeredObjectsstd::vector<BehaviourFactoryCallbackObject>BehaviourFactoryCallbackObject 包含用户给定的用于创建对象的函数。 此部分位于游戏引擎 (irrlicht) 创建的 .dll 中。

在游戏中,我从这个工厂创建了一个对象,并注册了一些用于创建对象的函数。

然后引擎(.dll)使用这个工厂。

问题是函数似乎没有正确注册,同时(根据 visual studio 的观察)它确实正确注册。

我如何初始化工厂和注册函数:

//This part is in the game, not the .dll
factory = new irr::AI::BehaviourFactory();
factory->RegisterBehaviour(ePID_SomeID, SomeBehaviour::GetInstance);

如果我按照这个进入工厂内部,那么新的 BehaviourFactoryCallbackObject 会正确添加到 registeredObjects(根据 visual studio 的观察)。但是,一旦我离开函数,registeredObjects 的大小就会调整回 0。 在某些时候,大小变为 1,但第 0 个元素包含无效地址作为其成员(而不是预期的函数指针)。

factory曾经是智能指针的一部分。我将其更改为普通指针,希望能解决此问题。除此之外,我尝试在 google/Whosebug 上搜索,但我不知道要搜索什么。

我的问题:有没有人知道可能是什么问题并且知道如何解决它?

工厂必须在游戏引擎中,我游戏中的代码必须在游戏中。 我用手表试过的东西: 观看 factory 并折叠它。 观看 factory->RegisteredObjects.size()。 我试图查看 RegisteredObjects 的地址,但没有成功。 如果 RegisteredObjects 的地址改变了 4 个或更多字节,我添加了一个断点。没有发生中断(添加元素后除外)。

附加代码:

//.h file, everything in this snippit is in the .dll
typedef IBehaviour* (* GetBehaviourCallBack) (void);

class BehaviourFactoryCallbackObject
{
public:
    BehaviourFactoryCallbackObject(int pID, GetBehaviourCallBack pFP) : id(pID), fp(pFP) { }
    int GetID();
    IBehaviour* BuildBehaviour();
private:
    GetBehaviourCallBack fp;
    int id;
};

class BehaviourFactory
{
public:
    BehaviourFactory(void) { }
    void RegisterBehaviour(int pID, GetBehaviourCallBack pFP);
    IBehaviour* GetBehaviour(int pID);
private:
    std::vector<BehaviourFactoryCallbackObject> registeredObjects;
};

//.cpp file
void BehaviourFactory::RegisterBehaviour(int pID, GetBehaviourCallBack pFP)
{
    //This vector does what I expect it to do but only when I am 
    //inside this function with the debugger
    registeredObjects.push_back(BehaviourFactoryCallbackObject(pID,pFP));
}

如果您需要任何其他信息,请说明。

编辑

一步步定位

下面的观察报告都检查同一个向量
我开始游戏,它创建了一个工厂。
我使用 RegisterBehaviour(pID, pFP)
向该工厂注册了一个函数 函数中的游戏步骤并在向量
中压入一个BehaviourFactoryCallbackObject Watch 报告矢量大小为 1
跳出函数,watch 报告矢量大小为 0
向工厂注册一个新函数,再次单步执行函数
现在观看报告大小为 1
推送新对象,Watch 现在报告大小为 2
再次走出去,手表报告大小为 0
注册新函数,进入函数
立即观看报告大小为 2
再次推送新对象,watch 报告大小为 3
走出去,再次观看大小为 0
的报告 完成注册,继续..

稍后我们实际使用工厂
此时 watch 报告大小为 1
第 0 个元素对于 fp 有一个无效地址,对于 id.
有一个巨大的负数 调试器因错误的 aloc 异常而中断。

您的问题没有提供足够的信息,因此很难写出准确的答案。说到这里,我来说说我的看法:

我怀疑在线:

registeredObjects.push_back(BehaviourFactoryCallbackObject(pID,pFP));

我一直对temporary objects心存疑虑。

尝试:

BehaviourFactoryCallbackObject BFC(pID,pFP);
registeredObjects.push_back(BFC);

我在另一个帖子中读到 VS2012 might have a bug on move semantics

您还可以进行以下测试:

BehaviourFactoryCallbackObject实现一个析构函数并在其中设置一个断点,并观察被调用的析构函数。如果析构函数被调用,那么当执行流离开函数范围时临时对象正在被销毁。

好在最后解决了。 包含工厂的对象已被删除,后来像这样使用:

if (delete)
    delete object;

//Some code..

return new fooObject(.., .., object->factory, ..);

原来是我傻

情况仍然很奇怪,我通过使用不同的编译器(在本例中甚至是不同的 IDE、xcode)发现了这个问题。这个调试器它的手表没有出问题,更容易找到问题。