c語言-動態內存分配

內存區域劃分(地址由高到低)

//本節紅色註釋是在寫的時候有模糊或忘記的地方,藍色是該注意的地方

1.棧區

2.堆區

3.靜態(全局區)

4.常量區

5.代碼區

棧區:由系統分配,主要存一些局部變量(主要是定義在函數體內)這些內存在函數使用完後由系統釋放,例如如下函數

void printAb (int a, int b);

void printAb(int a, int b){

print("%d %d", a, b);

}

如上述a, b在函數printAb調用完後,這樣a,b便得到釋放

注:棧區內的數據以棧的形式存儲,棧的特點:先進後出

//棧區的函數返回棧區的數據,是不安全的;因爲棧區的數據隨着函數執行結束,也會由系統自動回收回去,不能夠保證一直都能夠使用
int comeBack() {
    int x = 10;
    return x;
}//不安全

靜態全局區:全局變量和static修飾的變量都由系統在靜態全局區內存放

靜態變量是用static定義的變量

如:

for(int i = 0 ; i <  5; i++){

static int a = 1;

a++;

printf("%d ",  a);

}

這樣打印出的結果是2 3 4 5 6

注:用static修飾變量:存在於靜態全局區, 只能被初始化一次, 若沒有初始值,則默認爲0

靜態全局區的變量是在程序結束執行那時纔得到釋放,也是由系統自動分配,由系統分配.

常量區:主要存儲一些常量,如2, 3,4,yu ,"fdfd"等等

char *p = "ios";

*p = 'a'//這是錯的,指向常量區地址,修改的是常量區的地址,這是不允許的, 會發生崩潰的情況

注:常量區內的值只能讀取,不能修改

代碼區:  程序中的函數和語句被編譯成cpu指令存在於代碼區,代碼區也是由系統控制

堆區:由開發人員手動申請,手動控制

分配內存的函數

void *malloc(size_t); 返回值爲void *類型,這個被稱作是泛類型,泛類型可以轉換成任意一種指針類型,size_t是分配的字節數

int * p = malloc(sizeof(int)); p指向了一個分配一個整形大小的內存空間的首地址, p的地址是存在於棧區的,但是分配的地址是在堆區的,p裏面存的時一個堆區的地址.

在使用完內存之後要記得釋放

內存泄露:內存區域一直被佔用,得不到釋放

如下使用free(void *);

注:在釋放內存之後,如上面的 free(p); 需要使指針指向NULL(避免野指針)即 p = NULL;

這種釋放只是將該內存的標記設爲可用,而沒有清空裏面的內容(如果該內存沒有使用的時候標記爲0,一旦被分配即設爲1,這裏做的只是使裏面的1標誌設爲0).

void *calloc(n, size_t);

和malloc一樣,都是申請內存,並且calloc申請內存後,會對內存裏的內容做清空的操作;由於多了一步清空操作,效率要比malloc低. n:個數 size:字節數

calloc申請的內存字節數 = n * size;

eg: int *p6 = calloc(5, 4);

free(p6);

p6 = NULL;


void *realloc(p, size);

從p開始重新申請size個字節.

從地址p向後申請size個字節,如果後面可用的字節夠的話,就申請內存,並返回當前的指針p;如果不夠的話,會再去取內存中找一塊連續的空間,如果找到,就返回這一塊連續的空間的內存的首地址,並且把之前所佔用的內存釋放

   int *p7 = malloc(2);
    printf("%p\n", p7);
    p7 = realloc(p7, 170);
    printf("%p\n", p7);

以上是分配空間的還有如下幾個函數

void *memset(p,c , n);//從指針p的位置初始化n個字節的內存,把內容改成c

void *memcopy( p1,p2, n );//從指針p2的位置,向p1的位置,拷貝n個字節的內容

int memcmp(p1, p2, n);//比較p1和p2指向的內存所存放的內容是否相同,比較n個字節,相同返回爲0,不同返回差值

//棧區地址
  int a = 3;
  printf("&a = %p\n", &a);

  //堆區地址
 int *q = malloc(4);
    printf("q = %p\n", q);
    
   //靜態全局區
    printf("a1 = %p\n", &b);
    static int a2 = 2;
    printf("a2 = %p\n", &a2);

    //常量區
    char *string = "happy";
    printf("string = %p\n", string);
    
    //代碼區
    
    printHello();
    
    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章