C ++:奇怪的行为:return语句的返回值更改

时间:2012-07-10 13:53:59

标签: c++ memory-management return undefined-behavior

我的应用程序面临着非常非常奇怪的行为。

我将描述我的情况,然后解释出现了什么问题。

情况

我有一个带有这样签名的方法:

const StructureDef *getStructure(const std::string &theme, int index);

我在这段代码中称之为:

const StructureDef *sDef = 0;
do 
{
    sDef = ss->getStructure(theme, rand() % ss->availableStructureCount());
} while (!sDef);

我正在使用此do-while结构,因为getStructure方法的返回值可能为NULL,具体取决于themeindex的组合。所以基本上,它的作用是在我们获得有效结构之前询问随机结构。 (如果您想了解详细信息,请查看屏幕截图。)

该方法使用std::vector<StructureDef>迭代::iterator。对于每个StructureDef,它会检查结构是否属于该主题。如果是,则增加计数器并检查它是否等于请求的索引。像这样:

// inside the loop
if (i++ == index)

如果成功,则返回当前StructureDef *

return sDef;

出了什么问题

我正在使用XCode 4.4它的调试器来逐步查看正在发生的事情,这基本上就是gdb。

我首先解释的方法是找到符合我需要的StructureDef *。所以它返回指针。以下是在调试器中返回之前的时刻的屏幕截图:

Return point in the debugger

(for循环之后的行只是return 0;

此处指针sDef *指向0x1d563270,这是StructureDef的正确实例所在的位置。

下一个屏幕截图是我在调用该方法的代码段中得到的:

Caller gets wrong address

如您所见,获得方法返回值的指针sDef *现在指向0x2fe03804。这不是该方法返回的内容!我在想这是指针指向堆栈上的某个地方而不是堆。 (它应该是堆,因为std :: vector类将其对象存储在堆上,对吗?)。

我还不能使用Valgrind,因为我使用的是Mac OS X 10.8,Valgrind不支持。

我对这种行为感到非常惊讶。我不明白为什么会发生这种情况......可能是我的编译器坏了,还是做了一些奇怪的“优化”

提前致谢!
马亭


澄清DeadMG的评论:

我正在使用不同的主题:

iron
wood
ice

等...

我的标识符如下所示:

iron__downside_touch_and_go
iron__platform__700_65
iron__wall_bang
wood__platform__600_40

等...我想要做的是在一个主题中选择具有特定索引的结构。所以不是索引所有主题的结构集合在一起,而是一个主题的子集的索引。再看看这段代码:)


更新!!!

我提供了错误的信息。向量的类型为std::vector<StructureDef> !!它存储对象。不是指针!

那么(我认为)我正在使用.operator->()调用的内容与:&(*it)相同。它看起来像是在工作。写给我看起来有点愚蠢和*在彼此之后。


@Ben Voigt:

结构: enter image description here

优化: enter image description here

2 个答案:

答案 0 :(得分:2)

它看起来像我正在使用的调试器(LLDB而不是GDB,因为我虽然第一次)没有正确显示内存值。切换到GDB后,调试器显示了我看不到的内存地址。当我添加这样的打印语句时:

printf("StructureDef* pointer = %llx\n", (unsigned long long int)(void*) sDef);

看起来GDB是对的。出于测试目的,我切换回LLDB,并且神奇地它也正常工作。

也许,我正在处理这个人所写的内容:https://stackoverflow.com/a/9709462/155137

我希望它是LLDB调试器中的一个错误。因为,否则,我认为我的安装确实存在一些问题。

答案 1 :(得分:0)

将矢量从std::vector<StructureDef>更改为std::vector<StructureDef*>。当您使用其组成指针填充向量StructureDef时,为堆中的每个向量动态分配内存。