Question about iterators

I'm learning about iterators and operator precedence but I've run into this confusing problem. I can't seem to figure why the dereference operator is not taking precedence between these two:

++*iter
This one changes the value at which the iterator points to without changing the iter up.

*++iter

This seems to move the iterator up without changing any element values.

Is this because the two are considered "right-grouped" operators and so they combine like: *(++iter) ?
According to the C++ Standard
"Expressions with unary operators group right-to-left."


So expression

++*iter

means that at first you get the value pointed by the iter and then increase the value.

Expression

*++iter

means that at first you increase the iterator (so it will point to the next element in the sequence) and only then you get the value of the incremented iterator.
Last edited on
Thanks for the answer by the way. I wrote a bunch of code that would help me understand what was going on by printing memory addresses for objects and their elements and came upon this little oddity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void explain() {
    const char *cp = "123";
    const auto pr = &cp;
    const char *cp1 = &cp[1];
    const char *cp2 = &cp[2];
    
    if (cp && *cp) { 
        cout << "address of cp: " << &**pr << endl; 
        cout << "address of "<< cp[0] << ": " << &cp << endl; 
        cout << "address of "<< cp[1] << ": " << &cp1 << endl;
        cout << "address of "<< cp[2] << ": " << &cp2 << endl;

    }
}


address of cp: 123
address of 1: 0x7fff5fbff758
address of 2: 0x7fff5fbff748
address of 3: 0x7fff5fbff740


It seems weird to me that the memory addresses would move backwards rather than forward but I bet it's normal. Any idea what causes this and what I should read up on to understand it?
Last edited on
> cout << "address of "<< cp[1] << ": " << &cp1 << endl;

address of cp[1] is cp+1 or &(cp[1])

&cp1 is the address of the pointer cp1.


> what I should read up on to understand it?

1. Run this program and take a quick look at its output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <memory>

#define print_address(x) ( std::cout << "address of " #x " is " << std::addressof(x) \
                           << " (" << std::uintptr_t( std::addressof(x) ) << ")\n" )

void foo()
{
    int foo_a = 0 ;
    static int foo_b = 1 ;
    int foo_c[5] = { 2, 3, 4, 5, 6 } ;
    print_address(foo_a) ;
    print_address(foo_b) ;
    print_address( foo_c[0] ) ;
    print_address( foo_c[1] ) ;
}

void bar()
{
    int bar_a = 0 ;
    static int bar_b = 1 ;
    static int bar_c[5] = { 2, 3, 4, 5, 6 } ;
    print_address(bar_a) ;
    print_address(bar_b) ;
    print_address( bar_c[0] ) ;
    print_address( bar_c[1] ) ;

    std::cout << "--------------------------\n" ;

    foo() ;
}

int main ()
{
    int main_a = 0 ;
    static int main_b = 1 ;
    int main_c[5] = { 2, 3, 4, 5, 6 } ;
    print_address(main_a) ;
    print_address(main_b) ;
    print_address( main_c[0] ) ;
    print_address( main_c[1] ) ;

    std::cout << "--------------------------\n" ;

    foo() ;

    std::cout << "--------------------------\n" ;

    bar() ;
}

http://ideone.com/ft79XT

2. Read up on typical implementations of the memory layout of a program.
For instance, something simple (linux, no threads):
http://www.dirac.org/linux/gdb/02a-Memory_Layout_And_The_Stack.php

3. Now comeback and take a hard look at the output. Try to explain it.
address of cp[1] is cp+1 or &(cp[1])

&cp1 is the address of the pointer cp1.


That makes a lot of sense. I mistakenly thought it was printing the address to the individual element. I'm going to look over the code you pasted now.

/edit

Just wanted to say without bumping up this thread that things have become more clear. I realize now that static variables will go on the heap as opposed to the stack, which explains why they're being addressed in very different spaces in your example code.

Then because the stack grows downward, the variables I was declaring will go from a high address to a low one.

Thanks again for your help. That link you sent me is a goldmine.
Last edited on
Topic archived. No new replies allowed.