iOSDay08之C語言記憶體管理

2021-07-11 18:07:52 字數 4190 閱讀 5420

本次主要學習和理解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 = ;

23 student *p = malloc(sizeof

(student));

45 *p = stu;

*p是結構體指標,結構體指標訪問結構體成員變數的兩種方法如下:

第一種:(*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

int *p = malloc(sizeof(int

));2 *p = 10

;3 printf("

%d\n

", *p);

4free

(p);

5 p = null;

在c語言中訪問空位址的儲存空間會發生崩潰

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

int *p = malloc(sizeof(int

));2 *p = 10

;3 printf("

%d\n

", *p);

4free

(p);

5 printf("

%d\n

", *p); //

野指標異常

練習:輸入3個單詞,動態分配記憶體儲存單詞,並在最後輸出。

1

char *words[3] = ;

2char

string[30] = ;

3for (int i = 0; i < 3; i++)

13 printf("

輸出:\n");

14for (int i = 0; i < 3; i++)

在堆區申請n * size 個位元組的儲存空間,並把儲存空間的首位址返回

會將儲存空間做清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 *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);

在給定的位址空間開始,將 int 型的數值拷貝 size 次

1

int *p = malloc(sizeof(int

));2 memset(p, 0, 4); //

將p指向的儲存空間的資料置為0

從q指向的儲存空間開始拷貝size個位元組的資料到p指向的儲存空間

1

char name = "

hello";

2 memcpy(name, "

hi", 2

);3 printf("

%s\n

", name);

從p,q指向的位址開始比較size個位元組的資料,相等為0,不等為-1

1

int num1 = ;

2int num2 = ;34

int result = memcmp(num1, num2, sizeof(num1));//

相等為0,不等為-1

5 printf("

result = %d\n

", result);

C語言記憶體分布之資料段

不管我們以後是自己寫 還是讀別人的 都應該想想這個變數預設儲存的位置。在我們以後的嵌入式開發中,技巧性的 越來越多的時候,我們可能把某一些 放在一段。我們可以通過修改變數或者 預設放置的段,讓它被放到其它的段中。我們也可以自己定義乙個新的段。隨著執行,棧空間是隨時會變化的。棧空間臨時的去儲存一些變數...

C語言記憶體分布之資料段

不管我們以後是自己寫 還是讀別人的 都應該想想這個變數預設儲存的位置。在我們以後的嵌入式開發中,技巧性的 越來越多的時候,我們可能把某一些 放在一段。我們可以通過修改變數或者 預設放置的段,讓它被放到其它的段中。我們也可以自己定義乙個新的段。隨著執行,棧空間是隨時會變化的。棧空間臨時的去儲存一些變數...

C語言學習之動態記憶體管理

1 問什麼要動態記憶體管理?在進行資料儲存的時候,我們經常的做法是利用陣列開闢指定大小的空間用以儲存資料,但是陣列的具體大小取決於輸入的資料,因此往往在程式執行時才知道所需陣列的記憶體空間的大小。為了達到對記憶體空間的合理使用,這就要就我們根據輸入資料的不同來開闢不同大小的記憶體空間,繼而出現動態記...