動態內存/動態數組

一、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的程序:用篩選法找出素數

#define NUM 1000        //bug的主要來源
void SiftPrime(int n)
{
int *p = (int *)malloc(n*sizeof(int));
 assert(p != NULL);
 int i;
 for(i=0;i<n;i++)
 {
  p[i] = 1;    //默認爲1,是素數記爲1,不是素數記爲0
 }
 p[0] = 0;
 p[1] = 0;

 for(i=2;i<=sqrt((float)n);i++)
 {
  for(int j=i+1;j<n;j++)
  {
   if(j%i == 0)
   {
    p[j] = 0;
   }
  }
 }

 for(i=0;i<n;i++)
 {
  if(p[i] == 1)
  {
   printf("%d\n",i);
  }
 }
 free(p);
}

int main(void)
{
 SiftPrime(20);

 return 0;
}

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