版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344576
看一下set的iterator.由于map和set的相似性,只要看set就可以了.
1 #include <set>
2
3 void init( std::set<int>& set )
4 {
5 for ( int i = 0; i < 0x10; i++ )
6 {
7 set.insert( i );
8 }
9 }
10
11 int getSum( std::set<int>& set )
12 {
13 std::set<int>::iterator iter;
14 int result = 0;
15
16 for ( iter = set.begin(); iter != set.end(); iter++ )
17 {
18 result += *iter;
19 }
20
21 return result;
22 }
23
24 int main()
25 {
26 std::set<int> set;
27 init( set );
28
29 return getSum( set );
30 }
同样是看一下getSum的汇编:
(gdb) disassemble getSum
Dump of assembler code for function _Z6getSumRSt3setIiSt4lessIiESaIiEE:
0x080487a7 <+0>: push %ebp
0x080487a8 <+1>: mov %esp,%ebp
0x080487aa <+3>: sub $0x38,%esp
0x080487ad <+6>: lea -0x18(%ebp),%eax
0x080487b0 <+9>: mov %eax,(%esp)
0x080487b3 <+12>: call 0x8048914 <_ZNSt23_Rb_tree_const_iteratorIiEC2Ev>
0x080487b8 <+17>: movl $0x0,-0xc(%ebp)
0x080487bf <+24>: lea -0x1c(%ebp),%eax
0x080487c2 <+27>: mov 0x8(%ebp),%edx
0x080487c5 <+30>: mov %edx,0x4(%esp)
0x080487c9 <+34>: mov %eax,(%esp)
0x080487cc <+37>: call 0x8048922 <_ZNKSt3setIiSt4lessIiESaIiEE5beginEv>
0x080487d1 <+42>: sub $0x4,%esp
0x080487d4 <+45>: mov -0x1c(%ebp),%eax
0x080487d7 <+48>: mov %eax,-0x18(%ebp)
0x080487da <+51>: jmp 0x8048809 <_Z6getSumRSt3setIiSt4lessIiESaIiEE+98>
0x080487dc <+53>: lea -0x18(%ebp),%eax
0x080487df <+56>: mov %eax,(%esp)
0x080487e2 <+59>: call 0x80489c0 <_ZNKSt23_Rb_tree_const_iteratorIiEdeEv>
0x080487e7 <+64>: mov (%eax),%eax
0x080487e9 <+66>: add %eax,-0xc(%ebp)
0x080487ec <+69>: lea -0x10(%ebp),%eax
0x080487ef <+72>: movl $0x0,0x8(%esp)
0x080487f7 <+80>: lea -0x18(%ebp),%edx
0x080487fa <+83>: mov %edx,0x4(%esp)
0x080487fe <+87>: mov %eax,(%esp)
0x08048801 <+90>: call 0x8048982 <_ZNSt23_Rb_tree_const_iteratorIiEppEi>
0x08048806 <+95>: sub $0x4,%esp
0x08048809 <+98>: lea -0x14(%ebp),%eax
0x0804880c <+101>: mov 0x8(%ebp),%edx
0x0804880f <+104>: mov %edx,0x4(%esp)
0x08048813 <+108>: mov %eax,(%esp)
0x08048816 <+111>: call 0x8048948 <_ZNKSt3setIiSt4lessIiESaIiEE3endEv>
0x0804881b <+116>: sub $0x4,%esp
0x0804881e <+119>: lea -0x14(%ebp),%eax
0x08048821 <+122>: mov %eax,0x4(%esp)
0x08048825 <+126>: lea -0x18(%ebp),%eax
0x08048828 <+129>: mov %eax,(%esp)
0x0804882b <+132>: call 0x804896e <_ZNKSt23_Rb_tree_const_iteratorIiEneERKS0_>
0x08048830 <+137>: test %al,%al
0x08048832 <+139>: jne 0x80487dc <_Z6getSumRSt3setIiSt4lessIiESaIiEE+53>
0x08048834 <+141>: mov -0xc(%ebp),%eax
0x08048837 <+144>: leave
0x08048838 <+145>: ret
End of assembler dump.
同样可以看到set的this指针在ebp+0x8,iter的this指针在ebp-0x18
在0x08048825打断点.
看一下set的内容:
(gdb) x /x $ebp+8
0xbffff630: 0xbffff648
(gdb) x /8x 0xbffff648
0xbffff648: 0xbffff678 0x00000000 0x0804b050 0x0804b008
0xbffff658: 0x0804b170 0x00000010 0x080491f0 0x080486b0
(gdb) x /8x 0x0804b050
0x804b050: 0x00000001 0xbffff64c 0x0804b020 0x0804b0b0
0x804b060: 0x00000003 0x00000019 0x00000001 0x0804b080
(gdb) x /8x 0x0804b020
0x804b020: 0x00000001 0x0804b050 0x0804b008 0x0804b038
0x804b030: 0x00000001 0x00000019 0x00000001 0x0804b020
(gdb) x /8x 0x0804b0b0
0x804b0b0: 0x00000000 0x0804b050 0x0804b080 0x0804b110
0x804b0c0: 0x00000007 0x00000019 0x00000001 0x0804b0e0
(gdb) x /8x 0x0804b008
0x804b008: 0x00000001 0x0804b020 0x00000000 0x00000000
0x804b018: 0x00000000 0x00000019 0x00000001 0x0804b050
(gdb) x /8x 0x0804b038
0x804b038: 0x00000001 0x0804b020 0x00000000 0x00000000
0x804b048: 0x00000002 0x00000019 0x00000001 0xbffff64c
(gdb) x /8x 0x0804b080
0x804b080: 0x00000001 0x0804b0b0 0x0804b068 0x0804b098
0x804b090: 0x00000005 0x00000019 0x00000001 0x0804b080
(gdb) x /8x 0x0804b110
0x804b110: 0x00000001 0x0804b0b0 0x0804b0e0 0x0804b140
0x804b120: 0x0000000b 0x00000019 0x00000001 0x0804b140
(gdb) x /8x 0x0804b068
0x804b068: 0x00000001 0x0804b080 0x00000000 0x00000000
0x804b078: 0x00000004 0x00000019 0x00000001 0x0804b0b0
(gdb) x /8x 0x0804b098
0x804b098: 0x00000001 0x0804b080 0x00000000 0x00000000
0x804b0a8: 0x00000006 0x00000019 0x00000000 0x0804b050
(gdb) x /8x 0x0804b0e0
0x804b0e0: 0x00000000 0x0804b110 0x0804b0c8 0x0804b0f8
0x804b0f0: 0x00000009 0x00000019 0x00000001 0x0804b0e0
(gdb) x /8x 0x0804b140
0x804b140: 0x00000000 0x0804b110 0x0804b128 0x0804b158
0x804b150: 0x0000000d 0x00000019 0x00000001 0x0804b140
(gdb) x /8x 0x0804b0c8
0x804b0c8: 0x00000001 0x0804b0e0 0x00000000 0x00000000
0x804b0d8: 0x00000008 0x00000019 0x00000000 0x0804b110
(gdb) x /8x 0x0804b0f8
0x804b0f8: 0x00000001 0x0804b0e0 0x00000000 0x00000000
0x804b108: 0x0000000a 0x00000019 0x00000001 0x0804b0b0
(gdb) x /8x 0x0804b128
0x804b128: 0x00000001 0x0804b140 0x00000000 0x00000000
0x804b138: 0x0000000c 0x00000019 0x00000000 0x0804b110
(gdb) x /8x 0x0804b158
0x804b158: 0x00000001 0x0804b140 0x00000000 0x0804b170
0x804b168: 0x0000000e 0x00000019 0x00000000 0x0804b158
(gdb) x /8x 0x0804b170
0x804b170: 0x00000000 0x0804b158 0x00000000 0x00000000
0x804b180: 0x0000000f 0x00020e81 0x00000000 0x00000000
用图来表示如下:
看一下iter的变化:
(gdb) x /8x 0x0804b008
0x804b008: 0x00000001 0x0804b020 0x00000000 0x00000000
0x804b018: 0x00000000 0x00000019 0x00000001 0x0804b050
(gdb) c
Continuing.
Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610: 0x0804b020 0xbffff64c 0x0804b008 0x00000000
0xbffff620: 0xb7ff3170 0x00000001 0xbffff678 0x08048868
(gdb) x /8x 0x0804b020
0x804b020: 0x00000001 0x0804b050 0x0804b008 0x0804b038
0x804b030: 0x00000001 0x00000019 0x00000001 0x0804b020
(gdb) c
Continuing.
Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610: 0x0804b038 0xbffff64c 0x0804b020 0x00000001
0xbffff620: 0xb7ff3170 0x00000001 0xbffff678 0x08048868
(gdb) x /8x 0x0804b038
0x804b038: 0x00000001 0x0804b020 0x00000000 0x00000000
0x804b048: 0x00000002 0x00000019 0x00000001 0xbffff64c
(gdb) c
Continuing.
Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610: 0x0804b050 0xbffff64c 0x0804b038 0x00000003
0xbffff620: 0xb7ff3170 0x00000001 0xbffff678 0x08048868
(gdb) x /8x 0x0804b050
0x804b050: 0x00000001 0xbffff64c 0x0804b020 0x0804b0b0
0x804b060: 0x00000003 0x00000019 0x00000001 0x0804b080
(gdb) c
Continuing.
Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610: 0x0804b068 0xbffff64c 0x0804b050 0x00000006
0xbffff620: 0xb7ff3170 0x00000001 0xbffff678 0x08048868
(gdb) x /8x 0x0804b068
0x804b068: 0x00000001 0x0804b080 0x00000000 0x00000000
0x804b078: 0x00000004 0x00000019 0x00000001 0x0804b0b0
可以看到,set的iterator也只有一个成员_M_node,指向set的节点.而且set的iterator遍历是采用中序遍历法.