linux中环境变量和程序地址空间

环境变量

基本概念

  • 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写代码的时候,在链接的时候,从来不知道我们所链接的动静态库在哪,但是照样可以链接成功,生成可执行程序,原因是有相关变量帮助编译器查找
  • 环境变量具有全局性
    在这里插入图片描述

常见的环境变量

  • PATH:指定命令的搜索路径
  • HOME:指定用户的主工作目录(即用户登录到Linux系统中时,默认的目录)

查看环境变量的方法

echo $NAME //NAME:要查找的环境变量名

获取环境变量的方法

env                  #显示所有的环境变量
echo $XXX            #显示某个环境变量值
export MYENV=112233  #导环境变量
unset MYENV          #取消环境变量

环境变量的组织方式

在这里插入图片描述
每个程序都会收到一张环境变量表,环境表是一个字符指针数组,每个指针指向一个以'\0'结尾的环境字符串

通过代码获取环境变量

  • 命令行第三个参数
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[],char* env[])                                                                                                                     
{
    int i=0;
    for(;env[i];i++)
    {   
        printf("env[%d]:%s\n",i,env[i]);
    }   
}
  • 通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
	extern char **environ;
	int i = 0;
	for(; environ[i]; i++){
		printf("%s\n", environ[i]);
	} 
return 0;
}
  • 通过系统调用获取或设置环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("%s\n",getenv("PATH"));
    return 0;
}

常用getenv和putenv函数来访问特定的环境变量

程序地址空间

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int g_val=0;
int main()
{
    pid_t id=fork();
    if(id<0)
    {   
        perror("fork fail");
        return 0;
    }   
    else if(id==0)                                                                                                                                              
    {   
        //child
        printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);
    }   
    else
    {   
        //father
        printf("father[%d]:%d:%p\n",getpid(),g_val,&g_val);
    }   
    sleep(1);
    return 0;
}

输出
在这里插入图片描述
通过上面发现,输出出来的变量值和地址一摸一样

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int g_val=0;
int main()
{
    pid_t id=fork();
    if(id<0)
    {   
        perror("fork fail");
        return 0;
    }   
    else if(id==0)                                                                                                                                              
    {   
        //child
        g_val=100;
        printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);
    }   
    else
    {   
        //father
        sleep(3);
        printf("father[%d]:%d:%p\n",getpid(),g_val,&g_val);
    }   
    sleep(1);
    return 0;
}

在这里插入图片描述
发现,父子进程,输出地址是一致的,但是变量内容不一样

  • 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
  • 但地址一样,说明,该地址绝对不是物理地址
  • 在linux地址下,这种地址叫做虚拟地址
  • 我们在C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户看不到
    OS必须负责将虚拟地址转化成物理地址

进程地址空间

在这里插入图片描述
同一个变量,虚拟地址相同,内容不同其实是被映射到了不同物理地址

虚拟内存管理

描述linux下进程的地址空间的所有的信息的结构体是mm_struct(内存描述符)。每个进程只有一个mm_struct结构,在每一个进程的task_struct结构中,有一个指向该进程的结构
在这里插入图片描述

为什么要有虚拟地址空间

  • 将地址从无序变成有序
  • 地址转化过程中,可以对我们的地址和操作进行合法性判定,进而保护物理内存
  • 让内存管理和进程管理进行一定程度的解耦合

char str=“hello world”,str=‘H’;为什么字符常量区写入就会崩溃??
查找页表时,权限拦截了

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值