malloc函數動態分配內存


#include <stdio.h>
#include <stdlib.h>  //malloc  free
#include <windows.h>  //sleep
void main1(){
    //int a[1024*1024*1000]; //數組只能處理小數量的數據
    int num =100;
    //int b[num];  數組的大小必須明確,num是變量,隨時可以變化
    //數組內存這種分配機制就稱為靜態分配,數組使用完成后系統自動回收

    //動態內存分配
/*    malloc和free是C標准庫中提供的兩個函數,用以動態申請和釋放內存,malloc()函數的基本調用格式為:
    void *malloc( unsigned int size );
    參數size是個無符號整型數,用戶由此控制申請內存的大小,執行成功時,系統會為程序開辟一塊大小為size個內存字節的區域,並將該區域的首地址返回,
    用戶可利用該地址管理並使用該塊內存,如果申請失敗(比如內存大小不夠用),返回空指針NULL。
    malloc()函數返回類型是void*,用其返回值對其他類型指針賦值時,必須進行顯式轉換。
    size僅僅是申請字節的大小,並不管申請的內存塊中存儲的數據類型,因此,申請內存的長度須由程序員通過“長度×sizeof(類型)”的方式給出,舉例來說:
    int* p=(int*) malloc(5* sizeof(int) );
    Free就是釋放內存,例如free(p)
    */
    //輸入一個數字,並用float類型的數據初始化,形式:1.000,2.000 ... f
    float f;
    scanf("%f",&f);
    void *pVoid = malloc(f * sizeof(float));  //malloc返回值是空指針
    float *pFloat = (float *)pVoid;
   //下標法
    for (int i = 0; i < f; ++i) {
        pFloat[i] =i+1;
        printf("%f,%p \n",pFloat[i],&pFloat[i]);
    }
    //指針法
    printf("\n\n\n");
    float *p =pFloat;
    int fInt = (int)f;
    for ( int i = 0; p < pFloat + fInt; ++i,++p) {
        // p < pFloat + fInt此處的條件要注意,既然循環了,就要用p去循環, PFloat是不變的,切忌寫成 p < p + fInt,這樣的話 < 兩邊的p就一起動了
        *p = i+1;
        printf("%f,%p  \n",*p,p);
    }
    free(pVoid);  //釋放內存   pVoid是地址,只能free一次, NUll指針可以釋放多次
}
 void main2(){
    float f =3.0f;
    int a =(int) f;
    printf("%d,%f",a,a); //3,0.000000   一個很小的整數,按照%f來解析,會打印出 0.0000000
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main4(){
    int n;
    scanf("%d",&n);
    //double *pDouble = (double *)malloc(n * sizeof(double));  //malloc不會初始化
    double *pDouble = (double *)calloc(n, sizeof(double));  //calloc自動初始化內存為0
    for (double i = 0.0; i < n; ++i) {
        pDouble[(int)i] =i+1.0;  //i 強制轉換成int
        printf("%lf,%p\n",pDouble[(int)i],&pDouble[(int)i]);

    }
}

void main5(){
    int num;
    printf("please input the size of array:\n");
    scanf("%d",&num);
    int *p = (int *)malloc(num * sizeof(int));
    if(p==NULL)	/*防錯處理,看內存申請是否成功*/
    {
        printf("內存申請失敗,退出");
        return;
    }
    for (int i = 0; i < num; ++i) {
        p[i] =i+1;
        printf("%d,%p\n",p[i],&p[i]);
    }



    printf("if you want to rezize the array, please input a new number:\n");
    int newNum;
    scanf("%d",&newNum);
    //為已經分配的內存重新分配空間並復制內容
    // realloc()函數有兩個參數:已分配的內存地址,重新分配的字節數
    //	void *realloc( void *ptr, size_t size )
    int *newP = (int *) realloc((void *)p,newNum);
    //重新分配newNum字節的內存,並根據p的地址把原來malloc分配的內容復制過來
    printf("after realloc, p :%d,%p\n",*p,p);  // p :1,00030E58
    printf("after realloc, p+5 :%d,%p\n",*(p+5),p+5);  // after realloc, p+5 :13643,006D0E6C
    //似乎realloc后,沒有自動釋放掉p,但p的地址不變,只是所指向的類型為空指針


    for (int i = num; i < newNum; ++i) {   //注意因為前num個元素已經有realloc復制過來了,所以從num開始復制
        newP[i] =i+1;
    }
    //打印新的分配的數組
    for (int j = 0; j < newNum; ++j) {
        printf("%d,%p\n",newP[j],&newP[j]);
    }
    free(p);   //內存釋放以后,指針的值(地址)不會變化,只是把類型取消了
    free(newP);
}

/*
please input the size of array:
3
1,00020E58
2,00020E5C
3,00020E60
if you want to rezize the array, please input a new number:
6
1,00020E58    可以看到新分配的內存空間首地址是一樣的,可以得知舊的p指針所指向的那片內存空間后面任有剩余未占用的空間,所以繼續往后分配
2,00020E5C      如果舊指針p后面沒有剩余空間了,就會另外找一片內存區域,重新分配,舊的空間就自動釋放掉
3,00020E60
4,00020E64
5,00020E68
6,00020E6C*/

void main(){
    int num;
    printf("please input the size of array:\n");
    scanf("%d",&num);
    int *p = (int *)malloc(num * sizeof(int));
    if(p==NULL)	/*防錯處理,看內存申請是否成功*/
    {
        printf("內存申請失敗,退出");
        return;
    } else{
        for (int i = 0; i < num; ++i) {
            p[i] = i + 1;
            printf("%d,%p\n", p[i], &p[i]);
        }
        printf(" before free :%p\n",p);
        free(p);   //free 前后p的地址不會發生改變
        printf("after free :%p\n",p);
        p=NULL;  //軟件工程規范,釋放指針后要置為NULL,可以規避釋放后再次引用和反復釋放的問題
        printf("after free p[2]:%d\n",p[2]); //free之后,再次引用p[2]會出現垃圾數據,會報錯

    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM