我有以下代码(删除了一些代码以将其剥离到基本要素;所使用的几个方法/属性应该是自解释的):
void testApp::togglePalette(){
GraphicalEntity* palette= this->getEntityByName("palette-picker");
cerr << palette << endl;
}
GraphicalEntity* testApp::getEntityByName(string name){
list<GraphicalEntity*>::iterator j;
for(j=screenEntities.begin(); j!=screenEntities.end();++j){
if ((*j)->getTypetag() == name){
cerr << *j << endl;
return *j;
}
}
}
其中输出以下内容:
0x54bda0
0
我很困惑 - 为什么palette
中的togglePalette()
不等于getEntityByName
返回的地址(在当前情况下为0x54bda0),而是0
?
谢谢!
编辑:正如弗雷德在他的一篇评论中指出的那样,确实存在一个问题,即编译器在没有返回任何内容的情况下被代码到达函数末尾而感到困惑。
添加:
return (GraphicalEntity*) NULL;
在我的getEntityByName
方法结束时解决了这个问题。非常感谢!
我仍然感到困惑的是,为什么即使找到了对象,该方法也会返回0
(就像我实现我的代码的方式一样,已知总会找到一些东西) - 任何解释对此非常欢迎!
答案 0 :(得分:2)
根据我的评论,这是一个更完整的答案。
您的testApp::getEntityByName()
方法中有一个路径,其中控件退出方法而不返回值。根据您的编译器,体系结构和调用约定,这可能导致机器代码无法正常运行,即使您的流程从未经历错误的路径。
根据调用约定,调用方或被调用方法负责在方法返回之前或之后清理堆栈。返回值以及在内存中分配的位置是该约定的一部分,并且编译器期望函数始终返回相同的类型,无论函数内的控制流是什么。因此,它可以通过重新排列一些东西并生成特定的清理代码来根据调用约定来清理恢复堆栈来优化某些方法。在任何情况下,丢失的返回值都会使优化或清理变得混乱,因为它违反了编译器在处理代码时认为理所当然的情况,即每个路径都返回指向GraphicalEntity
对象的指针。如果没有这个假设会破坏堆栈或其内容,那么你最终会得到一个NULL指针(它可能已经崩溃或完成其他任何事情,它都是未定义行为的所有部分)。
答案 1 :(得分:0)
如果通过另一个线程访问screenEntities,可能会发生这种情况,因此“pallette-picker”已被删除或修改。然后getEntityByName函数将在调试模式下返回NULL。