# 方法
循环分配10000个类对象 然后查看内存空间源码在最下面
对c++类的虚函数有基本了解
# 编译命令
g++ -o memtest memtest.cpp -g -O0
1
# 直接开始
@luo:~/workspace/memtest# gdb memtest <----------------------- 使用gdb 调试memtest
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
...
...
Reading symbols from memtest...
(gdb) r <------------------------------------------------------开始运行
Starting program: /root/workspace/memtest/memtest
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) info proc <---------------------------------------------查看当前进程信息
process 2132 <------------------------------------------------ 当前进程pid
cmdline = '/root/workspace/memtest/memtest'
cwd = '/root/workspace/memtest'
exe = '/root/workspace/memtest/memtest'
(gdb) shell pmap -x 2132 <------------------------------------ 使用pmap查看内存映射
2132: /root/workspace/memtest/memtest
Address Kbytes RSS Dirty Mode Mapping
0000555555554000 4 4 4 r---- memtest
0000555555555000 4 4 4 r-x-- memtest
0000555555556000 4 4 0 r---- memtest
0000555555557000 4 4 4 r---- memtest
0000555555558000 4 4 4 rw--- memtest
0000555555559000 396 324 324 rw--- [ anon ] <------堆内存地址
00007ffff7a7d000 16 16 16 rw--- [ anon ]
00007ffff7a81000 12 12 0 r---- libgcc_s.so.1
00007ffff7a84000 72 72 0 r-x-- libgcc_s.so.1
00007ffff7a96000 16 16 0 r---- libgcc_s.so.1
00007ffff7a9a000 4 4 4 r---- libgcc_s.so.1
00007ffff7a9b000 4 4 4 rw--- libgcc_s.so.1
00007ffff7a9c000 52 52 0 r---- libm-2.31.so
00007ffff7aa9000 668 256 0 r-x-- libm-2.31.so
00007ffff7b50000 612 0 0 r---- libm-2.31.so
00007ffff7be9000 4 4 4 r---- libm-2.31.so
00007ffff7bea000 4 4 4 rw--- libm-2.31.so
00007ffff7beb000 136 136 0 r---- libc-2.31.so
00007ffff7c0d000 1504 848 8 r-x-- libc-2.31.so
00007ffff7d85000 312 172 0 r---- libc-2.31.so
00007ffff7dd3000 16 16 16 r---- libc-2.31.so
00007ffff7dd7000 8 8 8 rw--- libc-2.31.so
00007ffff7dd9000 16 12 12 rw--- [ anon ]
00007ffff7ddd000 600 600 0 r---- libstdc++.so.6.0.28
00007ffff7e73000 964 628 4 r-x-- libstdc++.so.6.0.28
00007ffff7f64000 292 164 0 r---- libstdc++.so.6.0.28
00007ffff7fad000 4 0 0 ----- libstdc++.so.6.0.28
00007ffff7fae000 44 44 44 r---- libstdc++.so.6.0.28
00007ffff7fb9000 12 12 12 rw--- libstdc++.so.6.0.28
00007ffff7fbc000 20 20 20 rw--- [ anon ]
00007ffff7fcb000 12 0 0 r---- [ anon ]
00007ffff7fce000 4 4 4 r-x-- [ anon ]
00007ffff7fcf000 4 4 0 r---- ld-2.31.so
00007ffff7fd0000 140 140 24 r-x-- ld-2.31.so
00007ffff7ff3000 32 32 0 r---- ld-2.31.so
00007ffff7ffc000 4 4 4 r---- ld-2.31.so
00007ffff7ffd000 4 4 4 rw--- ld-2.31.so
00007ffff7ffe000 4 4 4 rw--- [ anon ]
00007ffffffde000 132 12 12 rw--- [ stack ]
ffffffffff600000 4 0 0 --x-- [ anon ]
---------------- ------- ------- -------
total kB 6148 3648 548
计算方法 396*1024/8=50688
(gdb) x/50688a 0x0000555555559000 <----------------------- 查看堆内存地址数据
0x555555559000: 0x0 0x291
...
...
0x55555556aea0: 0x0 0x21
0x55555556aeb0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
0x55555556aec0: 0x0 0x21
0x55555556aed0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
0x55555556aee0: 0x0 0x21
0x55555556aef0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
0x55555556af00: 0x0 0x21
0x55555556af10: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
...
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
使用 c++filt翻译函数符号名称_ZTV7MEMTEST为MEMTEST虚表指针
root@luo:~/workspace/memtest# c++filt _ZTV7MEMTEST
vtable for MEMTEST
1
2
2
顺便查看一下虚函数表存的什么,~MEMTEST为虚析构函数地址(c++的多态相关)
(gdb) x/10a 0x555555557cd0
0x555555557cd0 <_ZTV7MEMTEST+16>: 0x555555555330 <MEMTEST::~MEMTEST()> 0x55555555534e <MEMTEST::~MEMTEST()>
1
2
2
在类中没有虚函数时的内存
0x55555556aea0: 0x0 0x21
0x55555556aeb0: 0xbb114514aa114514 0x0
0x55555556aea0: 0x0 0x21
0x55555556aeb0: 0xbb114514aa114514 0x0
1
2
3
4
2
3
4
在类中有虚函数时的内存
0x55555556aea0: 0x0 0x21
0x55555556aeb0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
0x55555556aec0: 0x0 0x21
0x55555556aed0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
0x55555556aee0: 0x0 0x21
0x55555556aef0: 0x555555557cd0 <_ZTV7MEMTEST+16> 0xbb114514aa114514
1
2
3
4
5
6
2
3
4
5
6
# 源码memtest.cpp
#include <iostream>
using namespace std;
class MEMTEST
{
public:
// 注释掉后就没有 虚表指针 0x555555557cd0 <_ZTV7MEMTEST+16>
virtual ~MEMTEST() {}
int i;
int j;
};
void f()
{
for (int i = 0; i < 10000; ++i)
{
//
MEMTEST *p = new MEMTEST;
p->i = 0xAA114514;
p->j = 0xBB114514;
}
throw std::bad_alloc();
}
int main()
{
f();
return 0;
}
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
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