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

Mar*_*aux 10 c++ memory-management return undefined-behavior

我的申请面临一种非常奇怪的行为.

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

情况

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

const StructureDef *getStructure(const std::string &theme, int index);
Run Code Online (Sandbox Code Playgroud)

我在这段代码中称它为:

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

我用这个做,而结构,因为返回值getStructure的方法可能是NULL,这取决于组合themeindex.所以基本上,它的作用是在我们获得有效结构之前询问随机结构.(如果您想了解详细信息,请查看截图.)

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

// inside the loop
if (i++ == index)
Run Code Online (Sandbox Code Playgroud)

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

return sDef;
Run Code Online (Sandbox Code Playgroud)

出了什么问题

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

我先解释的方法,找到StructureDef *符合我需要的方法.所以它返回指针.这是在调试器中返回之前的瞬间截图:

调试器中的返回点

(简单地说for-loop之后的行return 0;)

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

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

来电者得错地址

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

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

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

提前致谢!
马亭


澄清DeadMG的评论:

我正在使用不同的主题:

iron
wood
ice
Run Code Online (Sandbox Code Playgroud)

等等...

我的标识符如下所示:

iron__downside_touch_and_go
iron__platform__700_65
iron__wall_bang
wood__platform__600_40
Run Code Online (Sandbox Code Playgroud)

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


更新!

我提供了错误的信息.矢量属于std::vector<StructureDef>!! 它存储对象.不是指针!

那么(我认为)我正在进行的.operator->()呼叫与以下内容相同:&(*it).它看起来像是在工作.对我来说,写&和*之后看起来有点愚蠢.


@Ben Voigt:

建筑: 在此输入图像描述

优化: 在此输入图像描述

Mar*_*aux 2

看起来我使用的调试器(LLDB 而不是我首先想到的 GDB)没有正确显示内存值。切换到 GDB 后,调试器显示了我没有看到的内存地址。当我添加这样的打印语句时:

printf("StructureDef* pointer = %llx\n", (unsigned long long int)(void*) sDef);
Run Code Online (Sandbox Code Playgroud)

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

也许,我正在处理这个人写的内容:/sf/answers/679662371/

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