寒假学习 第二天 (linux 高级编程) 笔记 小结
一、linux 内存管理
接着昨天5.函数调用栈空间的分配与释放
函数执行时有自己的临时栈空间,c++成员函数有两个临时栈空间 一个是成员函数的还有一个是对象的
stdcall cdecl fastcall
决定函数栈压栈的参数顺序(这三个都是从右到左)
决定函数栈清空方式
决定函数的名字转换(windows)
nm 程序 时
c程序 add 函数名字就叫add c++因为有重载机制会 把名字 变成 列如 Z3addPis Z 是都有的3表示函数名字的长度后面的是函数形参类型
二、虚拟内存
#include<stdio.h>
#include<malloc.h>
int main()
{
int *p = malloc(4);
printf("%p\n",p);
while(1);
return 0;
}
输出 0xb7786018
#include<stdio.h>
#include<malloc.h>
int main()
{
int *p = (int*)0xb7786018;
printf("%d\n",*p);
return 0;
}
可能会出现段错误,或随机的值
一个程序不能访问另外一个程序的地址。
#include<stdio.h>
#include<malloc.h>
int main()
{
int *p = malloc(0);
*p = 222;
printf("%d\n",*p);
return 0;
}
输出
222
输出正常。原因见下面
为什么一个程序不能访问另外一个程序的地址。?
理解:
1.每个程序的开始地址都是相同的(这个就说明下面一条)
2.程序中使用的地址不是物理地址,而是逻辑地址(虚拟内存)
逻辑地址仅仅是个编号,它使用int 4字节整数表示 (4G)
每个程序提供了4G的访问能力
逻辑地址与物理地址关联才有意义,这个过程叫做内存映射
strace 程序
跟踪程序的执行过程
虚拟内存目的是为了禁止用户直接访问物理存储设备, 主要是为了系统的稳定
内存映射的基本单位 是 4k (即1000 16进制 叫内存叶)哪怕要1个字节 它映射的也是4k空间 malloc 第一次被调用的时候 不管你分不分配空间,它至少调用4k的空间。(所以上面的代码没有问题,肯定不会出现段错误)
段错误:地址没有映射到一个物理空间。无效访问。
合法访问:不出现段错误只是表示有效访问,不代表合法访问 。比如malloc 分配的空间之外的空间可以访问,但这是非法的(见上面的代码)
三、虚拟内存的分配
栈:编译器自己管理,我们不用管
堆:地址是否映射,映射的空间是否被管理
1.brk / sbrek 内存映射函数
int brk(void *addr); 分配空间,释放空间
void *sbrk(intptr_t increment); 返回空间地址
(这部分 还没搞定,明天再看)。