UNIX/Linux学习笔记(4)环境变量与内存
在学习笔记(3)中小编提到了如何设置环境变量,以及创建共享库时需生成位置无关的目标文件,这篇博客让小编和大家分享一下我所了解到的有关环境变量和内存的知识
环境变量
1)定义:
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置。环境变量以字符串形式存在,绝大多数据记录的是路径信息,它表示了当前操作系统的资源配置,环境设置等相关信息
2)环境变量表:
每个程序运行时,操作系统都会把所有的环境变量记录到一张表中,并传递给程序。通常我们有两种方法获取全局变量信息,第一,通过int main(int argc, char argv[],char* environ[])
中的char* environ[]
;第二,通过声明全局变量extern char** environ
3)环境变量函数:
①char* getenv(const char* name)
功能:根据环境变量名,获取环境变量的值
name:环境变量名的名称
返回值:若环境变量名不存在则返回NULL
,否则返回指向该处内容的指针
②int putenv(char* string)
功能:设置环境变量,若环境变量名存在则更新内容,不存在则添加
string:指针指向的内容为name = value
返回值:成功返回0,失败返回-1
③int setenv(const char* name, const char* value, int overwrite)
功能:设置name
环境变量的值为value
,如果name存在且overwrite
不为0则更新内容,如果name
不存在则添加
name:环境变量的名称
value:设置的环境变量值
返回值:成功返回0,失败返回-1
④int unsetenv(const char* name)
功能:从环境变量表中删除环境变量
name:环境变量的名称
返回值:成功返回0,失败返回-1
⑤int clearenv(void)
功能:清空环境变量表
返回值:成功返回0,失败返回-1
注意:在程序中添加环境变量需要自己为其准备对应的存储空间,而且对于环境变量的修改只能影响自己,不能影响别人
内存管理的方法
1)操作系统自动分配和释放内存 → 通过智能指针+STL → 调用标准C++的new/delete
2)new/delete 构造/析构 → C++ → 调用标准C中malloc和free
3)malloc/free → 标准C → 调用POSIX
4)brk/sbrk → POSIX → 调用Linux系统接口
5)mmap/munmap → Linux → 调用内核接口
6)kmalloc/vmalloc → 内核层 → 调用驱动
7)get_free_page → 驱动
进程映像
1)程序:保存在磁盘上的可执行文件
2)进程:加载到内存,并被操作系统调用执行的程序
3)进程映像:进程在内存空间中的分布情况,从低地址到高地址依次排列为:
虚拟内存
1)每一个进程都有自己独立的4G字节的虚拟地址空间,我们在编程时使用的永远都是这个4G虚拟地址空间中的地址,永远无法直接访问物理地址
2)操作系统不让程序直接访问物理地址的原因:① 操作系统自身的安全 ②让程序使用到比物理内存更大的空间
3)虚拟内存的划分:
4)映射:将虚拟内存与物理内存相对应,如果使用了没有映射的虚拟内存地址,或者访问了没有权限的虚拟内存地址,会产生段错误(非法的内存访问)
引申一下,像数组越界其实便是访问了没有映射的虚拟内存地址,访问字符串字面值便是访问了没有权限的虚拟内存地址
5)映射的大小:虚拟内存到物理内存的映射是以页为单位,1页 = 4K = 4096byte,如果访问地址范围太大由于翻页会消耗额外的时间
注意:一个进程对应一个用户空间,进程一旦切换,用户空间也随之改变;但是内核空间由操作系统管理,它不会随着进程的切换和变化
内存管理API
void* sbrk(intptr_t increment)
increment:0 → 获取未分配时内存的首地址
>0 → 增加内存空间
<0 → 释放内存空间
返回值:上次的末尾内存地址(本次未分配前的内存地址),以字节为单位
int brk(void* addr)
功能:设置未分配内存的首地址,例如:使用int* p=sbrk(4); *p=4;
获取上次的末尾地址并使用之后,通过brk(p)
设置当前的没分配内存的首地址,若提前记录之前的首地址并使用brk(start)
,即可起到释放内存的作用
返回值:成功返回0,失败返回-1
注意:上述两个函数都可以进行内存映射与映射取消,但为了方便起见,往往都是使用
sbrk
分配内存,brk
释放内存。它们背后维护的是一个指针,该指针记录的是未分配堆内存的首地址