linux-內存分配和動態庫靜態庫

1.內存分配:

  在linux中特有的內存分配方式有sbrk和brk,還有mmap(分配)和munmap(釋放)。當然還有更高層的malloc和free,new和delete還有,stl和智能指針

函數原型分別爲:

#include <unistd.h>//所在頭文件

int brk(void *addr);

void *sbrk(intptr_t increment);

void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);

int munmap(void *addr, size_t length);

函數說明分別爲:


#include <unistd.h>//所在頭文件

void *sbrk(intptr_t increment);
//參數increment>0時,當前位置指針向後移,表示分配內存空間,
//increment<0,當前位置指針向前移動,相當於釋放內存空間.
//increment=0,不會移動,返回當前位置,即:sbrk(0);

int brk(void *addr);
//brk函數的參數是一個地址,表示使用一個絕對地址來指定當前位置要移動到哪裏去,
//如果向後移動就是分配空間,向前就是釋放。

void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);//分配內存

/*void *addr,//指定映射的虛擬地址 0由系統指定開始位置)
size_t length,//映射空間大小 pagesize倍數
int prot,//映射權限  PROT_NONE | PROT_READ PROT_WRITE PROT_EXEC
int flags,//映射方式
int fd,//文件描述符號
offset_t off);//文件中的映射開始位置(必須是pagesize的倍數)
映射方式:
		內存映射:匿名映射。
		文件映射:映射到某個文件
						    只有文件映射最後兩個參數有效。
		
		MAP_ANONYMOUS 
		MAP_SHARED   MAP_PRIVATE(二選一)				*/

int munmap(void *addr, size_t length);
//void *addr 表示內存開始地址,size_t length 表示釋放內存的大小

函數示例

#include <unistd.h>
#include <sys/mman.h>//mem manage
#include <stdlib.h>
#include <stdio.h>
int main()
{
	int *p=mmap(//匿名
		NULL,//系統幫選擇首地址。
		getpagesize(),//頁大小。
		PROT_WRITE | PROT_READ,//read = r+w.
		MAP_ANONYMOUS|MAP_SHARED,//匿名分配。
		0,0);
	*p=20;
	*(p+1)=30;
	*(p+2)=40;
	munmap(p,4096);
	
	int *p = (int*)sbrk(4);//分配內存
	*p = 10;
	brk(p-4);//釋放分配的內存。
	
	return 0;
}

2.動態庫和靜態庫

庫是一組函數的集合,打包在一起供應用程序調用。本質是一種可執行代碼的二進制形式。
區別:
靜態庫(靜態庫要求做一般性掌握)在程序編譯時會被鏈接到目標代碼中,程序運行時將不再需要該靜態庫,因此代碼體積較大。
    創建過程:使用ar命令將一些.o文件,歸檔成一個.a文件。
	    gcc -c hello.c -ohello
	    ar -r libmyhello.a hello.o
    使用靜態庫
	    gcc main.c libmyhello -omain 

動態庫(比較重要)在程序編譯時不會被鏈接到目標代碼中,而是運行時才被載入,因此需要動態苦的存在,因此代碼體積小。
    命名規則:lib***.so
    編譯:
	-c -fpic(可選) f(文件格式) pic(位置 獨立 代碼)//gcc -c -fpic helloworld.c
    連接:
	-shared 		//gcc -shared -olibhello.so hello.o world.o
    使用:
	gcc 代碼   -l庫名 -L動態庫所在路徑 	//gcc main.c -lhello -L. -omain
    系統對動態庫查找:
	如果動態庫是在/lib 或者/usr/lib 路徑下那麼ld(linux的連接器)會默認找到他們,不需要其他操作
	如果在其他目錄下:那麼需要將庫添加到:/etc/ld.so.cache文件中
	    步驟1.編輯/etc/ld.so.conf文件,加入庫文件所在目錄的路徑。
		2.運行ldconfig,該命令會重建/etc/ld.so.cache文件
	當然也可以配置LD_LIBRARY_PATH環境變量中加上庫所在路徑。
	    例如:export LD_LIBRARY_PATH=.:~  (添加當前目錄和根目錄)

3.工具make的使用於makefile腳本

make工具是一種代碼維護工具,任務是根據makefile文件定義的規則和步驟,完成整個軟件軒昂母的代碼生成和維護工作,這樣可以大大街上編譯時間。

makefile文件編寫:

makefile文件的後綴名爲.mk。如下位demo.mk

compile:
	gcc -c -fpic input.c
	gcc -c -fpic primer.c
lnk:compile
	gcc -shared -olibdemo.so input.o primer.o
demo:lnk
	gcc demo.c -ldemo -L. -omain

其中第一行:是編譯源文件位目標文件。

第二行是:將兩個目標文件連接成libdemo.so的動態共享庫

第三行:是將main源文件與動態庫鏈接。

最後使用命令:

make -f demo.mk demo 
就會產生可執行文件:main




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章