在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