【问题标题】:trouble debugging c++ code pointer in Visual studio在 Visual Studio 中调试 c++ 代码指针时遇到问题
【发布时间】:2018-08-15 12:07:36
【问题描述】:

我想列出一个数组的每个成员及其对应的寄存器地址位置。这是我的代码

    // PointerDeferenceTest.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int main()
    {
        int x=0, y=0;
        int *px, *py;

        int number[15] = {-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9};
        while (x<14)
        {
            px = &x;
            py = number+x;
            cout << x+1 << ", " << px << ", " << *px << ", " << py << ", " <<  *py << ", " << py++ << ", " << *(py++) << ", " << *(++py) << "  \n";
            ++x;
        }
        return 0;

}

以 64 位运行得到以下意外结果

1, 000000D7532FF874, 0, 000000D7532FF904, -1, 000000D7532FF900, -3, -1
2, 000000D7532FF874, 1, 000000D7532FF908, 0, 000000D7532FF904, -2, 0
3, 000000D7532FF874, 2, 000000D7532FF90C, 1, 000000D7532FF908, -1, 1
4, 000000D7532FF874, 3, 000000D7532FF910, 2, 000000D7532FF90C, 0, 2
5, 000000D7532FF874, 4, 000000D7532FF914, 3, 000000D7532FF910, 1, 3
6, 000000D7532FF874, 5, 000000D7532FF918, 4, 000000D7532FF914, 2, 4
7, 000000D7532FF874, 6, 000000D7532FF91C, 5, 000000D7532FF918, 3, 5
8, 000000D7532FF874, 7, 000000D7532FF920, 6, 000000D7532FF91C, 4, 6
9, 000000D7532FF874, 8, 000000D7532FF924, 7, 000000D7532FF920, 5, 7
10, 000000D7532FF874, 9, 000000D7532FF928, 8, 000000D7532FF924, 6, 8
11, 000000D7532FF874, 10, 000000D7532FF92C, 9, 000000D7532FF928, 7, 9
12, 000000D7532FF874, 11, 000000D7532FF930, 0, 000000D7532FF92C, 8, 0
13, 000000D7532FF874, 12, 000000D7532FF934, -858993460, 000000D7532FF930, 9, -858993460
14, 000000D7532FF874, 13, 000000D7532FF938, -858993460, 000000D7532FF934, 0, -858993460

我无法弄清楚我做错了什么。第 4 列 (py) 开始列出数组中的第 4 项。但是代码设置为读取第一个(数字[0])。 我逗 W10 Visual Studio 社区 2017 编译 64 位

更新 1: 回应 PhoenixBlue 的评论。修改了数组样本以使用不同的数字。

更新 2:这是我的预期结果

   1, 000000D7532FF874, 0, 000000D7532FF904, -4, 000000D7532FF900, -3, -1
    2, 000000D7532FF874, 1, 000000D7532FF908, -3, 000000D7532FF904, -2, 0
    3, 000000D7532FF874, 2, 000000D7532FF90C, -2, 000000D7532FF908, -1, 1
    4, 000000D7532FF874, 3, 000000D7532FF910, -1, 000000D7532FF90C, 0, 2
    5, 000000D7532FF874, 4, 000000D7532FF914, 0, 000000D7532FF910, 1, 3
    6, 000000D7532FF874, 5, 000000D7532FF918, 1, 000000D7532FF914, 2, 4
    7, 000000D7532FF874, 6, 000000D7532FF91C, 2, 000000D7532FF918, 3, 5
    8, 000000D7532FF874, 7, 000000D7532FF920, 3, 000000D7532FF91C, 4, 6
    9, 000000D7532FF874, 8, 000000D7532FF924,4, 000000D7532FF920, 5, 7
    10, 000000D7532FF874, 9, 000000D7532FF928, 5, 000000D7532FF924, 6, 8
    11, 000000D7532FF874, 10, 000000D7532FF92C, 6, 000000D7532FF928, 7, 9
    12, 000000D7532FF874, 11, 000000D7532FF930, 7, 000000D7532FF92C, 8, 0
    13, 000000D7532FF874, 12, 000000D7532FF934, 8, 000000D7532FF930, 9, -858993460
    14, 000000D7532FF874, 13, 000000D7532FF938, 9, 000000D7532FF934, 0, -858993460

【问题讨论】:

  • 老实说,我在这段代码中根本看不出px 的意义。你在每次迭代中滥用py 上的前置和后置增量运算符是一场后勤噩梦。You may find this question and answer informative
  • py 分配了自己的内存,number 分配了自己的内存,并且从您的输出中,您打印了变量 py 的内存分配,因此它无法说明内存位置number 的任何项目,因此你不能说你的输出是否指向列表的任何位置。
  • @JoseECalderon '我看不到任何地方的增量' 你认为py++++py 是什么?
  • @JoseECalderon 不,不是。您误解了 C++ 是如何发生的。在表达式中,可以按任何顺序计算片段(有一些例外)。不能保证它会从左到右进行评估。有些编译器会从右到左,有些会做其他事情。
  • @JoseECalderon 你应该阅读 Whozcraig 发布的链接,它会解释你的误解。

标签: c++


【解决方案1】:

这段代码有问题py++ &lt;&lt; ", " &lt;&lt; *(py++) &lt;&lt; ", " &lt;&lt; *(++py)

在 C++ 中,您不应在同一表达式中使用同一变量的多个增量。

像这样重写你的代码

cout << x+1 << ", " << px << ", " << *px << ", " << py << ", " <<  *py << ", ";
cout << py++ << ", ";
cout << *(py++) << ", ";
cout << *(++py) << "  \n";

这应该可以解决一些问题,尽管正如 Msalters 所说,您还有其他问题。

【讨论】:

  • @datell 老实说我不确定。我认为完全正确的答案无论如何都取决于 C++ 的版本。我认为“不要这样做”就足够了。
  • @DanM。但这绝对是错误的。您的第二个代码很好,您的第一个代码是未定义的行为或未指定的行为(我不确定哪个)。
  • @DanM.:关联性决定了代码的解析方式,而不是执行方式。你的两个例子肯定是不同的。 C++ 中的语句按程序顺序排列,但子表达式不是。
  • @john:通常只是未指定的行为。在这种情况下,py 也会溢出 number[ ],从而将未指定的行为变为未定义的行为。
  • 更准确地说,可以肯定的是,这两个子句保证了预期的行为:更准确地说:Every overloaded operator obeys the sequencing rules of the built-in operator it overloads when called using operator notation.In a shift operator expression E1&lt;&lt;E2 and E1&gt;&gt;E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2。所以看起来因为 C++17 cout &lt;&lt; x++ &lt;&lt; x++; 确实具有与 operator &lt;&lt;(operator &lt;&lt;(cout,x++), x++) 不同的语义
【解决方案2】:

py 溢出,当x==13py=&amp;number[13] 在你增加两次之前。那是未定义的行为,它可能导致任何结果。

一旦你解决了这个问题,你可能会遇到更多的问题,但是未定义的行为非常严重,以至于你无法推断存在 UB 的小错误。 UB太糟糕了,它看起来像是“时光倒流”。你不能说“Foo 发生在 UB 之前,所以它应该不受它的影响”。既然UB可以做任何事,它也可以改变过去。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2022-08-02
    • 2013-12-19
    • 1970-01-01
    • 2020-02-04
    相关资源
    最近更新 更多