本次主要學習和理解c語言中的記憶體管理
按照位址從高到低的順序:棧區,堆區,靜態區,常量區,**區
區域性變數基本都在函式、迴圈、分支中定義
棧區的記憶體空間由系統自動分配和**
棧頂,棧底:先定義的區域性變數儲存區域從棧底開始分配,後定義的區域性變數向棧頂分配
特點:先進後出,後進先出
當函式、迴圈、分支結束後,區域性變數的生命週期結束,不能被使用,由系統自動**記憶體空間
1執行結果void
test1() 45
void
test2()
9int main(int argc, const
char *argv)
執行的結果a = 100是函式
test1()中的值,只是當函式test1()執行結束後,棧區
記憶體被自動**,但是棧區不會將資料清空,當函式test2()再定義乙個變數且不進行初始化時,輸出就是上個變數的值。
棧區的記憶體安全問題:在函式中返回棧區的位址是不安全的!
靜態區的記憶體空間由系統自動分配和**
生命週期和整個程式一樣長
1執行結果int test3(int
num)
6int main(int argc, const
char *argv)
為什麼第二次的執行結果是12呢?
因為用static修飾的變數稱為靜態變數,它只能初始化一次,第二次函式呼叫時,static int s = 5;
並沒有執行,故 s 的值為6,最後的結果是12
常量區的記憶體空間由系統自動分配和**
常量區的內容只能讀取不能修改
**區的記憶體空間由系統自動分配和**
**區的內容只能讀取不能修改
程式結束後,**區的記憶體空間由系統**
void * 為任意型別的指標
函式的作用:在堆區申請size個位元組的儲存空間,然後把儲存空間的首位址返回
在堆區申請一塊記憶體空間存放字串
1在堆區申請一塊記憶體空間存放結構體變數char str = "
zifuchuan";
2char *p = malloc(strlen(str) + 1);3
4strcpy(p, str);
5 printf("
%s\n
", str);
1 student stu = ;*p是結構體指標,結構體指標訪問結構體成員變數的兩種方法如下:23 student *p = malloc(sizeof
(student));
45 *p = stu;
第一種:(*p).成員變數名
1 printf("
第一種:(*p).成員變數名:name = %s, age = %d, gender = %c\n
", (*p).name, (*p).age, (*p).gender);
第二種:使用指向運算子:-> ,格式:結構體指標變數(p) -> 成員變數
1 printf("
第二種:使用指向運算子:->:name = %s, age = %d, gender = %c\n
", p->name, p->age, p->gender);
釋放開闢的儲存空間
完整的管理堆區記憶體**
1在c語言中訪問空位址的儲存空間會發生崩潰int *p = malloc(sizeof(int
));2 *p = 10
;3 printf("
%d\n
", *p);
4free
(p);
5 p = null;
1執行結果int *p = malloc(sizeof(int
));2 *p = 10
;3 printf("
%d\n
", *p);
4free
(p);
5 p =null;
67 printf("
%d\n
", *p);//訪問空位址
野指標異常
野指標:指標指向了不屬於自己管理的儲存區域
1練習:輸入3個單詞,動態分配記憶體儲存單詞,並在最後輸出。int *p = malloc(sizeof(int
));2 *p = 10
;3 printf("
%d\n
", *p);
4free
(p);
5 printf("
%d\n
", *p); //
野指標異常
1在堆區申請n * size 個位元組的儲存空間,並把儲存空間的首位址返回char *words[3] = ;
2char
string[30] = ;
3for (int i = 0; i < 3; i++)
13 printf("
輸出:\n");
14for (int i = 0; i < 3; i++)
會將儲存空間做清0操作,效率比malloc低
1執行結果int *p = malloc(sizeof(int) * 4
);2 printf("
%d %d %d %d\n
", *p, *(p + 1), *(p + 2), *(p + 3
));3
int *q = calloc(4, sizeof(int
));4 printf("
%d %d %d %d\n
", *q, *(q + 1), *(q + 2), *(q + 3));
在給定的位址空間的基礎上,如果當前指標的位址足夠大,那麼將位址擴大,如果空間不足,那麼重新找一塊新的儲存空間,然後釋放原來指標指向的儲存空間,把新的位址返回
1在給定的位址空間開始,將 int 型的數值拷貝 size 次int *p_old = malloc(sizeof(int
));2 printf("
%p\n
", p_old);34
int *p_new = realloc(p_old, 12
);5 printf("
%p\n
", p_new);
1從q指向的儲存空間開始拷貝size個位元組的資料到p指向的儲存空間int *p = malloc(sizeof(int
));2 memset(p, 0, 4); //
將p指向的儲存空間的資料置為0
1從p,q指向的位址開始比較size個位元組的資料,相等為0,不等為-1char name = "
hello";
2 memcpy(name, "
hi", 2
);3 printf("
%s\n
", name);
1int num1 = ;
2int num2 = ;34
int result = memcmp(num1, num2, sizeof(num1));//
相等為0,不等為-1
5 printf("
result = %d\n
", result);
C語言記憶體分布之資料段
不管我們以後是自己寫 還是讀別人的 都應該想想這個變數預設儲存的位置。在我們以後的嵌入式開發中,技巧性的 越來越多的時候,我們可能把某一些 放在一段。我們可以通過修改變數或者 預設放置的段,讓它被放到其它的段中。我們也可以自己定義乙個新的段。隨著執行,棧空間是隨時會變化的。棧空間臨時的去儲存一些變數...
C語言記憶體分布之資料段
不管我們以後是自己寫 還是讀別人的 都應該想想這個變數預設儲存的位置。在我們以後的嵌入式開發中,技巧性的 越來越多的時候,我們可能把某一些 放在一段。我們可以通過修改變數或者 預設放置的段,讓它被放到其它的段中。我們也可以自己定義乙個新的段。隨著執行,棧空間是隨時會變化的。棧空間臨時的去儲存一些變數...
C語言學習之動態記憶體管理
1 問什麼要動態記憶體管理?在進行資料儲存的時候,我們經常的做法是利用陣列開闢指定大小的空間用以儲存資料,但是陣列的具體大小取決於輸入的資料,因此往往在程式執行時才知道所需陣列的記憶體空間的大小。為了達到對記憶體空間的合理使用,這就要就我們根據輸入資料的不同來開闢不同大小的記憶體空間,繼而出現動態記...