一、malloc
1.常用表達式:int *p = (int *)malloc(n*sizeof(int));
爲20個char*分配內存 char **p = (char **)malloc(20*sizeof(char*));
2.malloc()內是所需申請的字節數,而malloc本身並不知道要申請什麼類型的字節,malloc本身的類型:
void *malloc( size_t size );若要返回指針類型,要使用強制類型轉換。
3.p一定是指向指針的開頭,不能p++,不然指針的指向發生移動,free崩潰
4.malloc在堆裏,堆的內存:1G左右
5.棧和堆的區別
棧:由系統自行管理
堆:程序自行管理
6.malloc申請內存,利用free釋放,如果沒有釋放,則出現內存泄漏
7.出現內存泄漏,則可用內存越來越少,設備速度越來越慢
8.內存泄漏很難解決的兩點原因
(1)程序退出,操作系統將程序消耗的內存全部回收
(2)關機。所有內存回到初始狀態
9.安裝vld小軟件,引用#include<vld,h>檢測內存泄漏
二、calloc
1.int *p = (int *)calloc(10,sizeof(int));
//10表示數組長度,sizeof(int)表示每個格子的大小,用的不多,實際上10*sizeof(int)就是malloc的表達,比malloc多了一步將數組初始化爲0
三、realloc
1.realloc:擴容 malloc想擴容,則用realloc
int *q = (int *)malloc(20*sizeof(int)); //創建新家
for(i = 0;i<10;i++)
{
*q[i] = *p[i]; //搬家
}
free(p); //釋放舊地址
p = q; //更新新地址
q = NULL; //淺拷貝發生錯誤,多個指針不能指向同一個內存,所以q = NULL
free(p); //若不加q=NULL,則free崩潰(重複釋放)
{ free(q);
2.int *p = (int *)realloc(20*sizeof(int)); //新的大小 重新分配20個格子的內存
3.若int *p = (int *)realloc(5*sizeof(int)); //即縮小容量會怎樣?
realloc可以對給定的指針所指的空間進行擴大或者縮小,無論是擴張或是縮小,原有內存的中內容將保持不變。當然,對於縮小,則被縮小的那一部分的內容會丟失。
4.(1)windows編譯器:重新申請一塊“地”
(2)gcc:補加一塊“地”
四、free
1.free如何得到長度信息?
malloc分配了兩個空間,一個是管理空間(記錄了管理信息),一個是實際空間,管理信息由結構體保存,如下:
struct mem_control_block {
int is_available; //這是一個標記?
int size; //這是實際空間的大小
};
而在結構體裏記錄了malloc申請的實際空間的大小,free釋放的是指針指向的內存大小,而不是指針,指針在程序結束時銷燬,由於free釋放了它指向的內存大小,所以它最後返回一堆垃圾,free的源代碼:
void free(void *ptr)
{
struct mem_control_block *free;
free = ptr - sizeof(struct mem_control_block);
free->is_available = 1;
return;
}
函數第二句中free的值減去一個結構體大小,釋放了實際空間,讓指針指向管理空間,然後管理空間裏的信息會告訴操作系統釋放實際內存的大小等信息。
http://blog.csdn.net/r91987/article/details/6337032
2.free崩潰的原因?
(1)越界
(2)指針的指向發生移動
(3)重複釋放
五、一些小知識
1.C語言中三大缺點
(1)內存泄漏
(2)內存越界
(3)數組太醜
其它變量的寫法:int a = 0; char *p = &a; 都是先分配好內存空間,再命名,而int Arr[10]則是先命名,再分配內存空間。
比如int Arr[10];原本按照定義是這樣寫的int [10]Arr;又例如
typedef unsiged long long uint64;
typedef int * Pint;
typedef int Arr[10];
typedef int (*Pfun)();
2.int *p:不能用sizeof(p)/sizeof(p[0]);
//error 結果是1,並不是想要求得的P的長度,如果P是數組則可用該公式
六、malloc的程序:用篩選法找出素數
{
assert(p != NULL);
int i;
for(i=0;i<n;i++)
{
p[i] = 1; //默認爲1,是素數記爲1,不是素數記爲0
}
p[0] = 0;
p[1] = 0;
{
for(int j=i+1;j<n;j++)
{
if(j%i == 0)
{
p[j] = 0;
}
}
}
{
if(p[i] == 1)
{
printf("%d\n",i);
}
}
free(p);
}
int main(void)
{
SiftPrime(20);
}