[C++系列] UNIX高级编程 day05 进程的映射。 物理地址映射到虚拟地址。malloc原理
in C/C++ with 0 comment

[C++系列] UNIX高级编程 day05 进程的映射。 物理地址映射到虚拟地址。malloc原理

in C/C++ with 0 comment

回顾

一,动态加载
二,程序中的错误处理
errno perror(3) stressor(3)
三,计算机的存储体系结构
寄存器。cache memery disk net
虚拟地址 物理地址 虚拟内存
裸板开发。可直接访问物理地址
代码段 数据段 栈段 堆
数据段 只读数据段 数据段 为初始化的数据段


#进程的映射

栈段 栈帧

函数的生命周期
进程的生命周期

#有的变量的生命周期函数的生命周期。有的是进程的生命周期。

静态的局部变量的空间分配在数据段。

作用域生命周期是两个概念。这两个可以协作完成任务

全局变量的空间分配在数据段

内部函数: 只能在改函数所在的源文件中调用,这样的函数称为内部函数。
外部函数

堆上分配内存:

#需要在程序中动态分配内存的时候,这时候从堆里分配内存,满足用户的需要。

最常见的是使用malloc(3)分配内存空间
brk sbrk mmap

悬空指针 也叫野指针

#使用mmap(2)将物理地址映射到进程的虚拟地址空间

#include<sys/mman.g>
Void *mmap(void *addr, size_t lenth, int port, int flags, int fd, off_t offset);

功能:建立文件或设备到内存的映射
参数
Addr: 指定虚拟地址的起始地址。
如果是NULL,虚拟地址由内核决定
Lenghth:指定映射区域的长度
Port:

     PROT_NONE   Pages may not be accessed.

     PROT_READ   Pages may be read.
     PROT_WRITE  Pages may be written.
     PROT_EXEC   Pages may be executed.

Flags;

MAP_PRIVATE: 不能被其它进程共享,也不能被更新到文件。
MAP_SHARED:可以被其它进程共享,在调用msync(2) or munmap(2)的时候,也被更新到文件。
MAP_ANONYMOUS: 不支持对文件的映射。如果指定了这个标记,fd参数和offset参数被忽略。fd也可以设置为-1;

Fd:文件描述符
Offset:文件的读写位置

返回值
如果成功返回一个指向映射区域的指针。
如果失败 MAP_FAILD((void *)-1). errno被设置
Int munmap(void *addr,size_t lenghth)

功能:接触设置
参数:
addr:是mmap(2)的返回值
lenghth:指定了映射区域的长度
返回值:
成功 0
失败: -1。 Errno被设置

#举例

使用mmap(2)映射物理地址到进程的虚拟地址空间,然后进行内存的操作。

1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<sys/mman.h>
  5 int main(){
  6         int prot=PROT_READ|PROT_WRITE;
  7         int flags=MAP_PRIVATE|MAP_ANONYMOUS;
  8         void *p=mmap(NULL,1024,prot,flags,-1,0);
  9         if(MAP_FAILED==p){
10         perror("mmap");
11         return -1;
12         }
13         //到这里p指向的内存就可以使用了
14         strcpy(p,"hello word");
15         printf("%s\n",(char *)p);
16         //解除映射
17         munmap(p,1024);
18         return 0;
19 }
~```
~
~

## `#`作业
大端和小端 ,编写代码实现

include<stdio.h>

2 int main(){
3 unsigned short var_s=0x0001;
4 char *p = &var_s;
5 if(!*p){
6 printf("big...n");
7 }else{
8 printf("littile..n");
9 }
10 return 0;
11 }

方式二:

include<stdio.h>

union val{
15 unsigned short num;
16 char p;
17 };
18 int main(){
19 union val v;
20 v.num = 0x0001;
21 printf("%dn",v.p);
22 return 0;
23 }

三,`malooc`的实现原理(`malooc`的`缓冲机制`)

CPU有时处在用户态,有时处在内核态。
在进程第一次调用malloc的时候,分配至少33块。然后从中取出一部分使用,在没有使用完之前,一致从缓存中取,
使用完毕,继续向系统申请。

## 举例:

1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<sys/types.h>
4 #include<unistd.h>
5 int main(){
6 printf("pid:%dn",getpid());
7 char p1 = (char )malloc(1024);
8 printf("p1:%pn",p1);
9 char p2 = (char )malloc(1024);
10 getchar();
11 return 0;
12 }
~`
通过cat /proc/pid/maps 来查看

练习

编写代码实现字符串的拷贝。程序中不允许使用库函数。

  1 #include<stdio.h>

  2 char *t_strcpy(char *desk,const char *src){
  3         char *d = desk;
  4         while(*src){
  5                 *d = *src;
  6                 d++;
  7                 src++;
  8         }
  9         *d  = '\0';
10         return desk;
11 }

12 int main(){
13         char arr[10];
14         char *p = "hello";
15         t_strcpy(arr,p);
16         for(int i=0;i<5;i++){
17                 printf("%c ",arr[i]);
18         }
19         printf("\n");
20         return 0;
21 }

#补充:

linux下一切皆文件
设备也被抽象为一个文件。

总结

一,内存的映射
二,使用mmap将物理地址映射到进程的虚拟地址空间
三,malloc的实现原理(缓冲机制)

Responses