10

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

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

情况

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

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,具体取决于 和 的theme组合index。所以基本上,它所做的是询问随机结构,直到我们得到一个有效的结构。(如果您想了解详细信息,请查看屏幕截图。)

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

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

如果此操作成功,StructureDef *则返回当前:

return sDef;

出了什么问题

我正在使用 XCode 4.4 它的调试器来一步一步地查看发生了什么,这基本上是 gdb。

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

调试器中的返回点

(for循环后的行很简单return 0;

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

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

来电者地址错误

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

我还不能使用 Valgrind,因为我在 Mac OS X 10.8 上,Valgrind 不支持它。

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

提前致谢!
马汀


澄清 DeadMG 的评论:

我正在使用不同的主题:

iron
wood
ice

ETC...

我的标识符如下所示:

iron__downside_touch_and_go
iron__platform__700_65
iron__wall_bang
wood__platform__600_40

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


更新!!!

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

那么(我认为)我在.operator->()通话中所做的与以下内容相同:&(*it). 看起来它正在工作。对我来说,在彼此之后写 & 和 * 看起来有点愚蠢。


@本·沃伊特:

建筑学: 在此处输入图像描述

优化: 在此处输入图像描述

4

2 回答 2

2

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

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

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

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

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

于 2012-07-10T14:59:54.977 回答
0

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

于 2012-07-10T15:07:57.490 回答