欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

uc第二天

程序员文章站 2022-07-16 10:44:29
...


--------内存管理--------

1。环境变量:
每个进程都有自己的环境变量表,环境变量表是一个char* 的数组。 指针数组,每个指针指向一个环境变量(字符串)。最后一个元素为NULL指针。这样就能够让程序知道什么时候结束不取值越界。
2。每个程序都有一个environ变量,指向该表头(指针数组首地址)extern char** environ; (这里要声明这个变量) char **p=environ while(*p){ printf(%s,*p) p++}
3。int main(int argc , char ** argv ,char **env )其实main函数他有第3个参数,那就是指向环境变量表的指针。
4。在C语言中,要想截取字符串,一般都使用指针的移动,和strncpy 来截取,strncmp比较前几个字符。
5。getenv("LANG") <stdlib.h>putenv("LANG=C") setenv("LANG","C",0)//0 不会修改,非0会修改。如果该变量不存在则增加到表中。 unsetenv("MYPATH") clearenv();//删除所有的环境变量,删除了仅仅是这个程序的环境变量表,其他程序不影响。
6。内存管理:
malloc / free -> new /delete STL 用自带的内存分配器来分配:allocator ,这样解决new delete 的效率执行开销问题。

高级---》 低级:

STL -> allocator
C++ -> new /delete
C -> malloc / free
----------------------------------------于平台无关的内存管理函数

仅仅是unix/linux 的:
brk / sbrk --> 系统不会多分配
mmap / munmap --》你自己想杂搞就杂搞
----------------------------------------应用级别的内存管理函数
kmalloc / vmalloc ...
get_free_page
----------------------------------------内核级别的内存管理函数

7。 new / delete 的区别:new 会构造其子对象,new 会调用构造,西沟函数, new 会自动进行类型转换滴。 这3项malloc都不会去做。
8。 new 与 new[] 不是一起的,是分别2个不同的运算符号。
9。 ***********每个进程的内存区域有这5大部分************
1。 代码/正文区域: 只读滴(1.全局的常量, 2 常量字符串 3)
2。数据缎/全局区域:(static 变量也保存在这里。 全局变量有初始化了的变量保存在这里。)
3。Bss段/全局区域: 他和全局区域在一起(全局变量未初始化的,都保存在这里,每次程序运行,bss段的空间都会初始化为 0 )
4。堆空间:自己分配,自己释放
5。栈空间:自动分配,自动释放局部变量要修改,我们要绕过编译器,去修改它。
10。cd /proc 放置内存程序分配状态 /proc/进程ID/maps --> 这个文件可以知道这个进程的实际物理内存地址情况(以页为单位滴)
11。为什么有些文件是0个字节,但是打开有 内容 呢? 因为在磁盘上并没有它,它只是在内存中而已。
12。为什么说:任何程序代码区都是从8048000开始的呢。

从现在开始:我们要从内存的角度去理解这些变量,因为系统他不关心类型,只关注字节是否足够。 4字节可以放整数,也可以放指针,所以可以当整数用字符串使用。因为,对C程序员来说:数据类型都是浮云一片片。
printf("%d %s %g ",*(int*)&buf , (char*)&buf+4 , *((double*)&buf+2) ); 分配空间--变量的定义。
13。堆空间中,空间的分配不是“连续“,因为用malloc来申请空间,其内部是维护着一个“双向链表的数据结构”所以空间后还有一些用于记录,前节点,后节点指针的空间,还有纪律结束标志的变量。所以,他们是节点来的,free一个空间,就是在mallco链表中删除一个节点罢了。


14。虚拟内存管理:(绝大部分的虚拟地址是没哟实际地址映射的。)
每个进程都有自己的虚拟内存地址,因为32位机器,int型最大可以表示4个G大小的地址,所以每个进程都可以有4G的地址表示。 其大家的地址都是相同的。这些都是虚拟地址。 虚拟地址必须要通过系统映射实际内存地址给它,我们才可以访问这个虚拟地址,否则段错误。
15。段错误2个问题: 1。 访问了,读了没有读权限的地址空间 2。 访问了没有映射好的虚拟地址空间 。
16。可以说:内存分配的本质是:内存映射。 虚拟地址还可以映射:文件,网络 等等。。。。
17。让最后一个堆空间越界为什么小一点就不越界,大一点点就越界了呢:因为其实系统给我们分配空间并不是我们想要多少才给多少的,系统它的对齐单位是1页的,在unix/linux下,是4k,即系统每次都会分配按照一页一页的空间来分配,至少一页了。所以其实越界也是可以的,只是不要越出最大页就好了。
18。getpagesize() 获取操作系统一页内存大小。
19 。 #include <unistd.h> unix/linux下的标准函数uni std .h
brk(sbrk(0)+5) 不关心开头,只关心我分配到那里结束就好了。所以通常我们使用sbrk(0)来告诉它,我们的开头和结尾。(往前:释放,往后:申请)。
sbrk(4) 分配字节空间他堆k(-4)释放字节空间堆 --------使用这2个函数是不会浪费空间的,要多少给多少。
20。底层函数实现:mmap / munmap 直接使用系统映射,这个空间我们随便用,不受类型的约束,他有6个参数罢了。