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