進程環(huán)境
本節(jié)主要介紹Unix的進程環(huán)境。
1.命令行參數(shù)和環(huán)境表
大多數(shù)Unix系統(tǒng)支持main
函數(shù)帶3個參數(shù):
int main(int argc, char *argv[], char *envp[]);
argc
表示命令行參數(shù)數(shù)目,argv
是指向參數(shù)的指針所構(gòu)成的數(shù)組历葛,envp
是環(huán)境表地址。
對于命令行參數(shù),可以通過下面的程序進行理解:
#include "apue.h"
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; i++) /* echo all command-line args */
printf("argv[%d]: %s\n", i, argv[i]);
exit(0);
}
執(zhí)行該程序可以的到:
命令行參數(shù)
環(huán)境表也是一個字符指針數(shù)組,其中每個指針包含一個以null
結(jié)束的C字符串的地址辽剧,全局變量environ
包含了該指針數(shù)組的地址。其結(jié)構(gòu)可以由下圖表示:
環(huán)境表
通乘安可以用getenv和putenv來訪問特定的環(huán)境變量怕轿,但是要查看整個環(huán)境,則必須使用environ
指針辟拷。
2.C程序的存儲空間
C程序一直由下列幾部分組成:
- 正文段撞羽。CPU執(zhí)行的機器指令部分,通成蓝常可以共享
- 初始化數(shù)據(jù)段诀紊。通常稱為數(shù)據(jù)段,包含程序中需明確地賦初值的變量
- 未初始化數(shù)據(jù)段隅俘。通常稱為bss段邻奠,存放未賦值的變量(通常初始化為0或空指針)
- 棧到推。自動變量以及每次函數(shù)調(diào)用時所需保存的信息都存放在此段中。每次函數(shù)調(diào)用時惕澎,其返回地址及調(diào)用者的環(huán)境信息都存放在棧中,然后最近被調(diào)用的函數(shù)在棧上為其自動和臨時變量分配存儲空間颜骤。
- 堆唧喉。通常在堆中進行動態(tài)存儲分配,通常堆位于未初始化數(shù)據(jù)段和棧直接忍抽。
下圖給出了存儲空間的典型布局:
存儲空間布局.png
3.共享庫
共享庫使得可執(zhí)行文件中不再需要包含公用的庫函數(shù)八孝,而只需在所有進程都可引用的存儲區(qū)中保存這種庫例程的一個副本。程序第一次執(zhí)行或者第一次調(diào)用某個庫函數(shù)時鸠项,用動態(tài)鏈接方法將程序與共享庫函數(shù)相鏈接干跛。
這樣的好處在于減少了每個可執(zhí)行文件的長度,缺點是增加了運行時間開銷祟绊,時間開銷主要發(fā)生在該程序第一次被執(zhí)行時楼入,或者共享庫第一次被調(diào)用時。
4.存儲空間分配
ISO C說明了3個用于存儲空間動態(tài)分配的函數(shù):
- malloc牧抽,分配指定字節(jié)數(shù)的存儲區(qū)嘉熊。此存儲區(qū)中的初始值不確定
- calloc,為指定數(shù)量指定字長的對象分配存儲空間扬舒。該空間中的每一位(bit)都設(shè)置為0.
- realloc阐肤,增加或減少以前分配區(qū)的長度。當增加長度時讲坎,可能需要將以前分配區(qū)的內(nèi)容移植到另一個足夠大的區(qū)域孕惜,以便在尾部提供增加的存儲區(qū),而新增區(qū)域初始值則不確定晨炕。
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
/* 返回值:成功返回非空指針衫画,失敗返回NULL*/
void free(void *ptr);