zoukankan      html  css  js  c++  java
  • c++内存管理5-虚拟内存4区结构图

      我们常说的32位系统为每个进程分配4G虚拟内存空间(而MMU负责把这些个4G虚拟内存映射到实际内存条的物理内存),其实只有0~3G才是真正完全属于进程本身,是我们所说的用户区;3~4G这1G是所有进程间共享的,是我们所说的内核区,我们的程序是无法直接访问内核区的。

    #include<stdio.h>
     
    int a;    //未初始化全局区 .bss
    int b=1;    //已初始化全局区  .data
    static int c=2;    //已初始化全局区  .data
    const int d=3;    //只读数据段,也叫文字常量区 ro.data, d的值不能被修改
    int main(void)
    {
        int e=4;    //栈区
        static int f=5;    //已初始化全局区
        const int g=6;    //栈区,不能通过变量名修改其值,但可通过其地址修改其值
        int *p=malloc(sizeof(int))    //指针变量p在栈区,但其所指向的4字节空间在堆区
        char *str="abcd";    //字符串“abcd”存在文字常量区,指针变量str在栈区,存的是“abcd”的起始地址
        return 0;
    }

      地方教材上常说:“全局变量在编译时分配空间,局部变量在运行时分配空间”,这在像vs这种集成式开发工具中,我们写个简单的程序,直接点个“运行”,编译、运行一步到位,很容易理解,但如果在linux上用vim写代码,用gcc编译生成a.out执行文件,再./a.out运行时,其实只剩下了“运行”这一步,那编译时分配又怎么解释呢?

      其实编译时就只是确定了全局变量(静态局部变量也算)的虚拟地址,并且相关信息存在了可执行文件a.out中。我们再说一个进程(即正在执行的可执行文件)大概有4种状态:就绪(等待cpu)—>运行(占用cpu)—>挂起(等待cpu之外的资源,主动放弃cpu)—>终止    另外:初始态为进程准备阶段,常与就绪合并 ,就是在这个初始态阶段,做了很多准备工作,其中一项就是根据全局变量的虚拟地址映射物理地址为其分配空间,并初始化好。所以全局变量在程序进入main()函数之前,就已经在内存中存在了,而局部变量和堆区变量就只有程序执行到声明(或定义)它的那一条语句,才开始为其申请分配空间。 

    参考博客:

      https://blog.csdn.net/m0_37829435/article/details/81158960

  • 相关阅读:
    C#中两个不同时间的相加减以及时间比较
    C#中一些报错处理
    C#将DataGridView中的数据导出为EXCEL
    C# tabcontrol的tabpage切换
    C# DataGridView控件中数据导出到Excel
    C#将数据导入到excel中 出现 “object”未包含“get_Range”的定义
    SQL Server数据库的备份与还原以及在项目中是怎样去实现的 (网摘)
    android各组件详解
    刚刚做得一个Android开发教程的专题
    一个Demo让你掌握所有的android控件
  • 原文地址:https://www.cnblogs.com/icmzn/p/11824802.html
Copyright © 2011-2022 走看看