C语言 利用malloc()和realloc()动态分配内存
生活随笔
收集整理的這篇文章主要介紹了
C语言 利用malloc()和realloc()动态分配内存
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1. C語(yǔ)言定義1個(gè)數(shù)組的時(shí)候, 必須同時(shí)指定它的長(zhǎng)度.
例如:? int a[5]={1,2,3,4,5}; //合法 int b[6]; //合法int c[]; //錯(cuò)誤 因?yàn)闆](méi)有指定長(zhǎng)度
但是下面語(yǔ)句是正確, 它隱形定義了數(shù)組的長(zhǎng)度, 就是賦值元素的個(gè)數(shù)
int d[] ={4,5,6,7,8,9} //合法 長(zhǎng)度為6
2. 靜態(tài)數(shù)組
??????? 什么是靜態(tài)數(shù)組,? 其實(shí)上面合法定義的數(shù)組都是靜態(tài)數(shù)組.
??????? 靜態(tài)數(shù)組并不是指數(shù)組里面的元素是靜態(tài)的,? 上面的數(shù)組都可以修改指定元素的指
??????? 而是指數(shù)組的元素個(gè)數(shù)是靜態(tài)的,? 也就是某1個(gè)靜態(tài)數(shù)組一旦被定義, 那么在程序運(yùn)行結(jié)束的這段時(shí)間里它的長(zhǎng)度的都是不變的.
??????? 也就是說(shuō)當(dāng)你定義1個(gè) 靜態(tài)數(shù)組a[5]
???????? int a[5]={1,2,3,4,5};
????????
???????? 你就不能修改a 的長(zhǎng)度了.
3.動(dòng)態(tài)定義數(shù)組的個(gè)數(shù)
???????? 有時(shí)我們需要1個(gè)數(shù)組, 但是數(shù)組的元素個(gè)數(shù)不是固定的, 是個(gè)變量,? 那么我們是否可以利用如下語(yǔ)句
???????? int i = 7;int a[i]; //定義1個(gè)長(zhǎng)度為i的數(shù)組?
????????
???????? 上面的寫(xiě)法可以能在java .net 里面是可行的, 但是c語(yǔ)言里是不合法的, 不能這樣定義1個(gè)數(shù)組.? 數(shù)組的長(zhǎng)度必須是1個(gè)常量.
???????? 但是經(jīng)本人測(cè)試,? 上面的寫(xiě)法已經(jīng)被最新的gcc支持了 囧
???????? 正確的寫(xiě)法:
???????????????int len =7; int * a = (int *) malloc (sizeof(int) * len);
??????????????? int * a 就是頂定義1個(gè)int類(lèi)型的指針啦.
??????????????? 其中 sizeof(int) 就是4 (byte) 啦? ,??
???????????????? malloc (sizeof(int) * len)??????? 就是在內(nèi)存劃出 4* len = 28個(gè)字節(jié)的內(nèi)存, 并返回第1個(gè)字節(jié)(最小內(nèi)存單位)的地址
???????????????
??????????????? malloc函數(shù)是返回1個(gè)地址的, 但是只有地址是沒(méi)有意義的.? 因?yàn)橐堰@個(gè)地址賦值給1個(gè)int類(lèi)型指針的話(huà),要將其格式化.
??????????????? 所以malloc 前面要加上(int *) 就是把malloc 返回的地址格式化成1個(gè) int類(lèi)型的地址.
??????????????? 可以理解成這個(gè)int類(lèi)型的地址是4個(gè)字節(jié)1個(gè)單位的,? 只要獲得這個(gè)地址, 就獲得后面3個(gè)地址的內(nèi)容啦.
??????????????? 所以上面藍(lán)色的語(yǔ)句就的得到了1個(gè)指
???????? 正確的寫(xiě)法:向 1個(gè) 長(zhǎng)度為7的int類(lèi)型數(shù)組指針a.
??????????????? 后面就可以把a(bǔ) 當(dāng)作一般的數(shù)組名a來(lái)處理了.
??????????????? 最后注意一點(diǎn), 使用malloc函數(shù) , 必須引用malloc.h? 或者 stdlib.h頭文件.
4.動(dòng)態(tài)數(shù)組占用的釋放
???????????????? 定義1個(gè)靜態(tài)數(shù)組int a[7],? 那么在函數(shù)結(jié)束被調(diào)用或程序結(jié)束前的時(shí)間里, 這28個(gè)字節(jié)是容易被這個(gè)數(shù)組占用的.
?
????????????????? 而動(dòng)態(tài)分配(malloc函數(shù)分配)的內(nèi)存 在程序運(yùn)行的時(shí)間內(nèi)可以被釋放.? 然后被其他對(duì)象使用.
????????????????? 例如:
???????????????? int len =7;int * a = (int *) malloc (sizeof(int) * len);// 這里可以把數(shù)組a 當(dāng)作普通數(shù)組來(lái)使用free(a); //釋放這個(gè)數(shù)組a所占的28個(gè)字節(jié)的內(nèi)存.//注意 是釋放指針a所指向的內(nèi)存, 而不是釋放指針a本身占用的內(nèi)存.// 注意不能釋放靜態(tài)變量或數(shù)組的空間.// 注意 經(jīng)由malloc 分配的動(dòng)態(tài)內(nèi)存. 必須手動(dòng)釋放
?????????????????? 這樣的話(huà). 優(yōu)點(diǎn)很明顯. 因?yàn)榭梢詣?dòng)態(tài)分配和釋放, 比其靜態(tài)定義要節(jié)省內(nèi)存啊.
5.動(dòng)態(tài)數(shù)組長(zhǎng)度的增加.
??????????????? 這個(gè)就是動(dòng)態(tài)數(shù)組跟靜態(tài)數(shù)組區(qū)別最大的地方了, 動(dòng)態(tài)數(shù)組的長(zhǎng)度可以改變啊.
??????????????? 接上面的例子
???????????????
????????????????? int len =7;int * a = (int *) malloc (sizeof(int) * len);
???????????????? 上面定義了1個(gè)長(zhǎng)度為7 的動(dòng)態(tài)數(shù)組,? 這時(shí)我發(fā)現(xiàn)這個(gè)數(shù)組不夠用了, 想給它加1個(gè)元素,值是40,也就是令他的長(zhǎng)度+1
??????????????
???????????????? 直接
???????????????? *(a+7) = 40; //合法, 也可能通過(guò)編譯和執(zhí)行. 但是這個(gè)是錯(cuò)誤的寫(xiě)法.
??????????????? 為什么說(shuō)上面的寫(xiě)法是錯(cuò)誤的呢,? 因?yàn)槲覀冎唤o指針a 分配了1個(gè)字節(jié)為28byte的連續(xù)內(nèi)存空間.
??????????????? 就是 從a[0] 到 a[6]了
??????????????? 那么a[7]是什么呢,? 明顯就是a[6]后面接著的4個(gè)字節(jié)的內(nèi)存空間啊.?
?????????????? 但是這個(gè)空間有可能被其他對(duì)象或其他程序正使用中的, 以后也可能被使用,? 這樣未執(zhí)行分配指令就直接使用的話(huà)就很有可能改變了其他對(duì)象或程序中的內(nèi)存內(nèi)容,? 這就是所謂的不安全行為.
??????????????? 那應(yīng)該怎么做?
?????????????? 就用到另一函數(shù)? realloc()?? 重新分配指針a所占的長(zhǎng)度.
????????????????? 例如:
????????????????
int len =7;int * a = (int *) malloc (sizeof(int) * len);len++;int * aold = a; //重新分配前保存a的地址 這個(gè)是多余的a = (int *)realloc(sizeof(int)* len); //重新分配28+4 = 32字節(jié)內(nèi)存給數(shù)組a
???????????????? 我們來(lái)分析一下上面4條語(yǔ)句
???????????????? 前面兩句定義了1個(gè)長(zhǎng)度為7的int 類(lèi)型數(shù)組, 每個(gè)元素的字節(jié)長(zhǎng)度是4, 所以共占28byte 內(nèi)存.
???????????????? 第3句長(zhǎng)度變量+1
???????????????? 第4句 分兩種情況:
??????????????????????????? 1) 假如數(shù)組a 內(nèi)存里接著的4個(gè)字節(jié)還沒(méi)被其他對(duì)象或程序占用, 那么就直接把后面4個(gè)字節(jié)加給數(shù)組a, 數(shù)組前面7個(gè)舊的元素的值不變,? 數(shù)組a的頭部地址也不變.
???????????????????????????? 2) 假如數(shù)組 a內(nèi)存里接著的4個(gè)字節(jié)已經(jīng)被占用了, 那么realloc 函數(shù)會(huì)在內(nèi)存其他地方找1個(gè)連續(xù)的32byte 內(nèi)存空間, 并且把數(shù)組a的7個(gè)舊元素的值搬過(guò)去,? 所以數(shù)組a的7個(gè)舊元素的值也不變, 但是數(shù)組a的頭部地址變化了.? 但是這時(shí)我們無(wú)需手動(dòng)把舊的內(nèi)存空間釋放. 因?yàn)閞ealloc 函數(shù)改變地址后會(huì)自動(dòng)釋放舊的內(nèi)存, 再手動(dòng)釋放程序就會(huì)出錯(cuò)了, 我被坑過(guò)啊
下面的代碼就是多余, 也是錯(cuò)誤的.
if (aold != a){ //如果a的地址改變了, 代表內(nèi)存在另外1個(gè)地方劃分1個(gè)新的內(nèi)存空間free(aold); //把舊空間釋放}
???????????????? 但最終效果都一樣的, 就似是我們可以動(dòng)態(tài)地給動(dòng)態(tài)數(shù)組a增加多1個(gè)元素的內(nèi)存空間.
????????????????? 注意: realloc 函數(shù)不能用在靜態(tài)數(shù)組的指針上,? 即使通過(guò)編譯. 執(zhí)行時(shí)也會(huì)出錯(cuò).
????????????????
?5.一個(gè)簡(jiǎn)單的例子程序:
int malloc_3(){int len = 7;int * a = (int *)malloc(sizeof(int) * len);int i;for (i=0; i <len ; i++){a[i] = (i+1)*2;} i = p_array_int_1(a,len); //a function to print the array which defined by user printf("address is %p\n", a);len++;//a = (int *)realloc(a, sizeof(int)* (len));i = re_malloc(&a, len);a[len-1]= 40;i = p_array_int_1(a,len); //a function to print the array which defined by user printf("address is %p\n", a);free(a);return 0; }int re_malloc(int ** pa, int len){int * pold;*pa = (int *)realloc(*pa, sizeof(int)* (len));if (pold != *pa){free(pold);}return 0; }
? ?
輸出:
總結(jié)
以上是生活随笔為你收集整理的C语言 利用malloc()和realloc()动态分配内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Oracle 的检查点队列 (check
- 下一篇: C语言 跨函数使用内存.