关于返回对象地址的困惑

Confusion about returning the address of an object

本文关键字:地址 对象 于返回 返回      更新时间:2023-10-16

我有以下代码(删除了一些代码以将其剥离到要点;使用的两个方法/属性应该是不言自明的):

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

我很困惑——为什么togglePalette()中的palette不等于getEntityByName返回的地址(在当前情况下是0x54bda0),而是等于0

谢谢!

EDIT:正如Fred在他的一条评论中指出的,这确实是一个编译器被到达函数末尾却没有返回任何内容所混淆的问题。

添加:

return (GraphicalEntity*) NULL;

在我的CCD_ 5方法的最后解决了这个问题。非常感谢!

尽管如此,我仍然困惑于为什么即使找到了对象,该方法也会返回0(就像我实现代码的方式一样,众所周知总会找到一些东西)——对此的任何解释都非常受欢迎!

根据我的评论,这里有一个更完整的答案。

testApp::getEntityByName()方法中有一条路径,在该路径中,控件退出该方法而不返回值。根据您的编译器、体系结构和调用约定,这可能会导致机器代码无法工作,即使您的流从未通过错误的路径

根据调用约定,在方法返回之前或之后清理堆栈是调用者或被调用方法的责任。返回值以及它在内存中的分配位置是该约定的一部分,编译器希望函数始终返回相同的类型,无论函数中的控制流是什么。因此,它可以通过重新排列一些内容和生成特定的清理代码来优化一些方法,以根据调用约定清理还原堆栈。在任何情况下,丢失的返回值都可能会破坏优化或清理,因为它违反了编译器在处理代码时认为理所当然的内容,即每个路径都返回一个指向GraphicalEntity对象的指针。如果假设失败,则会损坏堆栈或其内容,并且您最终得到一个NULL指针(它可能已经崩溃或做了其他任何事情,这都是未定义行为的一部分)。

如果通过另一个线程访问screenEntities,从而删除或修改了"托盘选择器",则可能会发生这种情况。然后getEntityByName函数将在调试模式下返回NULL。