【Linux操作系统】-- 程序地址空间

本文详细探讨了Linux操作系统中程序的虚拟地址空间,包括mm_struct结构体、数据代码与虚拟地址的关系,以及虚拟地址如何通过页表和MMU转化为物理地址。通过实例解释了写时拷贝原理,阐述了地址空间对于内存管理和进程隔离的重要性。
摘要由CSDN通过智能技术生成

目录

 

虚拟地址的内部结构

虚拟地址

mm_struct虚拟地址结构体

数据代码和虚拟地址的结合

 虚拟地址的其他结构


虚拟地址的内部结构

 这张图中可以看到内存地址中按从低地址到高地址排列的内存块,分别是代码区,字符常量区,数据区包括未初始化的和已初始化的,堆。而栈的地址是从高地址到低地址。

可以通过代码来验证一下(Linux环境下)

int g_unval;
int g_val=100;

int main()
{
  const char* s="hello world";
  printf("code addr:%p\n",main);//代码区
  printf("string rdonly addr:%p\n",s);//(字符串)常量区
  printf("uninit addr:%p\n",&g_unval);//未初始化数据区
  printf("init addr:%p\n",&g_val);//初始化数据区

  char* heap =(char*)malloc(10);
  printf("heap addr:%p\n",heap);//堆

  printf("stack addr_string:%p\n",&s);//栈--栈上的临时空间
  printf("stack addr_heap:%p\n",&heap);
  
  int a=10,b=20; 
  printf("stack addr_a:%p\n",&a);//验证栈区地址是由大到小
  printf("stack addr_b:%p\n",&b);
  return 0;
}
[wjy@VM-24-9-centos 407test]$ ./mycode
code addr:0x40057d                   //代码区
string rdonly addr:0x400700          //字符常量区
uninit addr:0x601044                 //未初始化数据区
init addr:0x60103c                   //初始化
heap addr:0x199a010                  //堆
stack addr_string:0x7ffd05938bc8     //栈
stack addr_heap:0x7ffd05938bc0
stack addr_a:0x7ffd05938bbc
stack addr_b:0x7ffd05938bb8

那么C/C++的程序地址空间,是内存吗?

验证一下,写一个mycode.c的C语言程序。定义一个全局变量,这样父子进程用到这个值都会是这个值。当fork()创建子进程,结果为0就是子进程,如果不为0,fork()值为子进程的pid,那么就是父进程。当两个进程一样的时候,二者共用一份代码,一份数据。当子进程有改变的时候,就会发生写时拷贝。

[wjy@VM-24-9-centos 407test]$ cat mycode.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int g_val=100;
int main()
{
  //数据是各自有一份(写时拷贝)
  if(fork()==0)
  {
    //child
    int cnt=5;
    while(cnt)
    {
      printf("I am child,times:%d,g_val=%d,&g_val:%p\n",cnt,g_val,&g_val);
      cnt--;
      sleep(1);
      if(cnt==3)//当cnt值为3改变g_val的数据
      {
        printf("###############  child changed data   ################\n");
        g_val=200;
        printf("###############  child changed done   ################\n");
      }
    }
    exit(0);
  }
  else{
    //parent
    while(1)
    {
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值