0

I will like to list each member of an array listed with its corresponding register address location. Here is my code

    // 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;

}

Running at 64 bits getting the following unexpected result

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

I cannot figure out what I am doing wrong. The 4th column (py) is starting to list the 4th item in the array. But the code is set to read the first (number[0]). I amusing W10 Visual studio community 2017 compile 64 bit

UPDATE 1: In response to PhoenixBlue comment. Amended the array sample to use different numbers.

UPDATE 2: This is my expected result

   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
  • It is not the 4th Item. It's the first. You can try with an array of all different values. The problem is, you are incrementing the pointer at some point, so it will skip some values! – PhoenixBlue Aug 15 '18 at 12:12
  • 1
    I honestly don't see the point of `px` in this code whatsoever. And your abuse of pre and post increment operators on `py` with each iteration is a logistical nightmare.[You may find this question and answer informative](https://stackoverflow.com/questions/3986361/behavior-of-post-increment-in-cout) – WhozCraig Aug 15 '18 at 12:22
  • @PhoenixBlue I change the array sample. Continues to read from the 4th item. I don't see the increment anywhere. py=number+x. But x is 0 when starting the loop. – Jose Enrique Calderon Aug 15 '18 at 12:24
  • 1
    `py` has its own memory allocated, `number` has its own memory allocated, and from your output, you have printed memory allocations of variable `py`, so it can not state the memory location of any of the item of `number`, therfore you cannot say if your output in anyway pointing any location of the list. – Muhammad Areeb Aug 15 '18 at 12:24
  • 1
    @JoseECalderon 'I don't see the increment anywhere' what do you think `py++` and `++py` are? – john Aug 15 '18 at 12:26
  • @john .. yes..you are correct. But the instruction is AFTER the actual first cout of py.. Therefore .. why the increment is occurring in the 4th column of the first line? – Jose Enrique Calderon Aug 15 '18 at 12:31
  • 2
    @JoseECalderon No it isn't. You are misunderstanding how C++ occurs. In an expression the pieces can be evaluated in any order (with some exceptions). There is no guarantee that it will be evaluated left to right. Some compilers will go right to left, and some will do something else. – john Aug 15 '18 at 12:32
  • 1
    @JoseECalderon You should read the link that Whozcraig posted, it will explain your misunderstanding. – john Aug 15 '18 at 12:34
  • @Jabberwocky edited post to show my expected result. I want to forth column to list each item of the array. – Jose Enrique Calderon Aug 15 '18 at 12:42
  • OK, john's answer is correct. Your problems comes from the abuse of the `++` operator. Also read WhozCraig's comment. – Jabberwocky Aug 15 '18 at 12:44
  • @ WhozCraig px is a pointer . &x is filling the variable with an address. – Jose Enrique Calderon Aug 15 '18 at 12:56

2 Answers2

5

This code is a problem py++ << ", " << *(py++) << ", " << *(++py).

In C++ you should not use multiple increments of the same variable in the same expression.

Rewrite your code like this

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

That should fix some of the problems although as Msalters says you have other problems as well.

john
  • 85,011
  • 4
  • 57
  • 81
  • Would be nice if you could provide an explanation for your statement. Does this lead to undefined behaviour? – dtell Aug 15 '18 at 12:31
  • Pretty sure it doesn't, due to the associativity. I.e. `cout << x++ << x++;` is no different than `cout << x++; cout << x++;`. – Dan M. Aug 15 '18 at 12:35
  • 1
    @datell To be honest I'm not sure. I think the totally correct answer depends on the version of C++ in any case. I think 'don't do this' is enough. – john Aug 15 '18 at 12:36
  • 1
    @DanM. But this is defintely wrong. Your second code is fine, your first is undefined behaviour or unspecified behaviour (I'm not sure which). – john Aug 15 '18 at 12:37
  • 1
    @DanM.: Associativity determines how the code is parsed, not how it's executed. And your two examples are certainly different. _Statements_ in C++ are sequenced in program order, but _subexpressions_ are not. – MSalters Aug 15 '18 at 12:40
  • @DanM. "...is not different than...", you're mistaken. An equivalent expression is considerably more complicated than that. it looks like this: `operator <<(operator <<(cout,x++), x++)` In fact, that is literally what the compiler sees as it compounds `cout << x++ << x++;` – WhozCraig Aug 15 '18 at 12:41
  • 1
    @john: It would normally be only unspecified behavior. In this case, `py` also overflows `number[ ]`, which turns the unspecified behavior into undefined behavior. – MSalters Aug 15 '18 at 12:42
  • @WhozCraig yes. And it has exact same meaning as `x++; cout << x++;` which I said. I'm not stating that every `x op y op z` is equivalent to `x op y; x op z;` that'd be ridiculous. it was undefined before, but pretty sure it became well-defined in C++17. Or at very least unspecified (`cout << x << x++;` is 100% defined though). – Dan M. Aug 15 '18 at 12:57
  • 2
    More precisely, pretty sure that the expected behavior is guaranteed by these two clauses: More precisely: `Every overloaded operator obeys the sequencing rules of the built-in operator it overloads when called using operator notation.` and `In a shift operator expression E1<>E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2`. So it looks like since C++17 `cout << x++ << x++;` indeed has different semantics than `operator <<(operator <<(cout,x++), x++)` – Dan M. Aug 15 '18 at 13:00
4

py overflows, when x==13, and so py=&number[13] before you increment it twice. That is Undefined Behavior, which may result in any outcome.

You probably will have more issues once you've fixed this, but Undefined Behavior is so severe that you cannot reason about minor bugs in the presence of UB. UB is so bad, it can appear to "travel back in time". You can't say "Foo happened before the UB, so it should be unaffected by it". Since UB can do anything, it can also change the past.

MSalters
  • 173,980
  • 10
  • 155
  • 350