GDB Debug Note

gcc -g main.c -o main.out

才可以被gdb调试

gdb ./main.out

  • l列出源代码
  • break 12 设置断点
  • start 开始单步调试
  • p a 打印 a 变量
  • n 回车next
  • s step 单步 ,跳函数
  • bt 查看函数堆栈
  • f 1 切换到堆栈1

32位cpu 最大内存只有4G

32位cpu地址总线是32位,寻址空间是32位,给内存的编号只能编到32个二进制位, 2^32 = 4GB

64位cpu 可以管理内存 ..PB ..PE

  • 2^30 ~ G
  • 2^40 ~ T

操作系统认为 64位下 前48位(0x7fffffffffffffff)给用户使用就足够,以上交给操作系统

Bash
- 操作系统内核
- 栈
- 自由空间 
- 堆
- 数据段
- 代码段

栈 ,记录执行过程中的状态,执行到哪里,变量如何。 变量的本质就是内存。指针的本质是保存内存的地址。

操作系统如何管理内存

全局变量,静态数据,放在数据段中。 全局变量永远保存在一个地方全局特有 静态变量属于每个函数特有的,对于相应的函数来说存在于一个地方。 但都不会压入栈中。

int 变量 32 位 4个字节

64位操作系统 ,指针 8个字节

gcc 编译器会对内存分配做优化,把同类型变量放在一起,指针运算会更快。

最先分配的栈,地址最大,从顶部向下分配,一般main函数最大

函数指针

Shell Session
int (*pquardrate)(int a) = &quardrate;
int s = (*pquardrate)(a)

已经知道地址,取变量 pquardrate 是一个地址 *pquardrate 解除引用,取存在地址处的值 如果这个指针指向的是栈内存、数据段内存,会取数据。 如果指向的是代码段,会取代码块。 (*pquardrate) 表示函数代码块整体

数组和指针运算

函数内部的数组,存到栈中,从小到大连续排放

指针的加减 按照指针类型加减 int *p 每次加减4个字节

指针偏移运算效率非常高 p+=3表示把指针偏移三格,移动12个字节, p[3]p+=3效果一样,但 p+=3 改变了指针 p 的值,p[3]只是做了偏移。通常

Shell Session
int *p = &a;
p += 3;
*p = 101;
Shell Session
int *p = &a;
p[3] = 101;

数组(指针常量)本身就是指针,都可以通过[]做偏移,但是不能改变: array += 3不可以;

Shell Session
int array[2];
int *pa = array;
pa[0] = 1;

字符串数组 也是指针

Shell Session
char str[] =="hello";
char *str2 = "word";
char str3[10];
scanf("%s",str3);

str3 本身就是地址,直接传到scanf() str2 是一个指向字符串的指针,其内容是“word”这个字符串所在的地址,可能在数据段代码段,很小,不允许修改。 只可以在栈内存和堆内存中修改。

strstr3是连续分配的,如果输入超出,会写到其他变量中。