Confusion about returning the address of an object
I have the following code (some code removed to strip it to the essentials; the couple methods/attributes used should be self explanatory):
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;
}
}
}
Which outputs the following:
0x54bda0
0
I'm confused- why isn't palette
in togglePalette()
equal to the address returned from getEntityByName
(so 0x54bda0 in the current case), but to 0
?
Thanks!
EDIT: As Fred pointed out in one of his comments, it was indeed an issue of the compiler being confused by the code reaching the end of the function without returning anything.
Adding:
return (GraphicalEntity*) NULL;
at the end of my getEntityByName
method solved the problem. Thanks a l开发者_如何学JAVAot!
I'm still confused by why the method would return 0
even if the object is found (as in the way I implement my code, it is known that there will always be something found) though- any explanation on that would be more than welcome!
Following on my comment, here's a more complete answer.
There is a path in your testApp::getEntityByName()
method where control exits the method without returning a value. Depending on your compiler, architecture and calling convention, this could result in machine code that doesn't work even if your flow never goes through the erroneous path.
Depending on the calling convention, it is either the caller or the called method's responsibility to clean up the stack before or after the method returns. The return value, and where it is allocated in memory, is part of that convention, and a compiler expects a function to always return the same type no matter what the control flow within the function is. Because of that, it can optimize some methods by rearranging some stuff and generating specific clean-up code to clean restore the stack according to the calling convention. In any case, the missing return value can mess up that optimization or clean-up because it violates what the compiler took for granted when it processed your code, i.e. that every path returned a pointer to a GraphicalEntity
object. Failing that assumption corrupted the stack or its content, and you ended up with a NULL pointer (it might as well have crashed or done just about anything else, it's all part of undefined behavior).
It could happened if screenEntities is accessed via another thread so the "pallette-picker" has been removed or modified. Then getEntityByName function will return NULL in debug mode.
精彩评论