3

我遇到了一个非常奇怪的问题,其中某些变量的监视窗口值似乎与它们的“真实世界”值不匹配。调试器似乎在空间中关闭。这是显示它的最小代码片段:

printf("%d", pNodes[nNode].nColumn); // watch shows "4"
printf("%d", nColumn); // watch shows "1"

if (pNodes[nNode].nColumn != nColumn)
  continue; // this is NOT called

所以这是行为:

  1. 如果我将手表添加到pNodes[nNode].nColumn,它显示的值为4
  2. 如果我将手表添加到nColumn,它显示的值为1
  3. 如果我检查 pNodes[nNode].nColumn != nColumn监视窗口中的表达式,它的计算结果为true.
  4. continue语句被跳过!
  5. 我添加了printf()调用以查看发生了什么,并printf()打印了值11,这似乎与代码“流动”的方式一致(即它不调用内部continue语句if

我什至可以检查内存&pNodes(nNode].nColumn,内存显示监视窗口显示的“不正确”值。因此,调试器似乎与实际程序数据或其他东西完全“断开连接”。我正在运行调试构建优化已关闭。我还检查了 pNodes 不对应于某个全局变量或范围更高的其他变量——似乎只有一个本地版本。

这对我来说完全莫名其妙!我什至不确定下一步该去哪里试图找出问题所在。如果您有任何想法,我很想听听他们的意见!

谢谢!

4

3 回答 3

5

所以我想我已经破案了:罪魁祸首是Struct Member Alignment。我有一堆项目混合在一起,其中一些项目在项目中的这个字段具有不同的值。我删除了所有这些设置,让 VS 选择默认值,问题就消失了。

适用的值在某些项目中介于4 字节之间,在某些项目中为默认值,在其他项目中完全为空。该值位于Configuration Properties/ C/C++ / Code Generation / Struct Member Alignment下。同样,我最终只是完全删除了项目的值。我认为这是在过去的某个时候在项目上设置的,以处理某种跨平台问题,但至少它对于我现在正在做的工作是固定的!

感谢您所有的帮助!

于 2011-09-01T22:35:22.570 回答
2

If watches are set using variables not in scope, that is the sort of behavior I see all the time with Visual Studio. It really should say "<not in scope>" or something more useful.

If you are stepping through these lines of code and you still see those ghostly values, I don't know: are you sure it is a debug build?

于 2011-09-01T22:08:31.520 回答
0

Visual Studio 2010 调试器在跟踪监视变量内存位置方面存在问题。有时它会严重误导你,因为 VS2010 没有显示你认为它显示给你的变量。

例如,如果您在函数中重用变量名,那么随着执行范围的变化,应在监视窗口中显示哪个内存位置:

for (int i=0; i<10; i++) {
   i=i+1; // do something, what isn't important
}

int i;
for (i=0; i<5; i++) {
  i=i+1; // do something 
}

printf("i=%d\n", i);

现在将变量i放在监视窗口中。

显然,在监视窗口中显示哪个 i(或值)很重要。如果你运行程序,你会看到当它进入 for 循环时,手表会跟踪 for 循环的 i 变量。当它退出 for 循环,然后使用另一个同名变量访问下面的代码时,监视窗口不会跟踪该变量的内存。

你会看到监视窗口仍然声明 i 是 10,即使在第二个循环中我现在是 0,1,2,...并且在第二个循环之后我实际上是 6,但监视窗口仍然声明 i 是 10。

监视窗口应该做什么?我会争辩说,它应该始终向您显示具有该手表名称的变量的值,即在范围内,因为语言规则告诉您在任何给定时间只有一个变量在范围内。

这是调试器的监视窗口功能中的一个错误(VS2010 似乎很便宜地找到了函数中与您在手表中给出的名称相匹配的第一个变量,并顽固地监视那个内存空间,不管代码中可能还有什么,即使具有相同名称的新变量已接管范围(此时监视窗口现在对您撒谎!)

于 2014-08-01T20:29:45.940 回答