程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> C語言之free函數以及野指針介紹

C語言之free函數以及野指針介紹

編輯:更多關於編程
    以下是對C語言中的free函數與野指針進行了詳細的分析介紹,需要的朋友可以參考下  

    【FROM MSDN && 百科】
    原型:void free(void *ptr);
    #include<stdlib.h>或#include <malloc.h>
    Deallocate space in memory
    釋放ptr指向的存儲空間。被釋放的空間通常被送入可用存儲區池,以後可在調用malloc、realloc以及realloc函數來再分配。
    注意:連續兩次使用free函數,肯定會發生錯誤。malloc的次數要和free的次數相等。
    A block of memory previously allocated using a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.
    If ptr does not point to a block of memory allocated with the above functions, the behavior is undefined.
    If ptr is a null pointer, the function does nothing
    Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location
    DEMO:

    復制代碼 代碼如下:
    //#define  FIRST_DEMO
    #define  SECOND_DEMO
    #ifdef FIRST_DEMO
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    int main(void)
    {
     int *buffer1,*buffer2,*buffer3;
     buffer1=(int *)malloc(100*sizeof(int));
     buffer2=(int *)calloc(100,sizeof(int));
     buffer3=(int *)realloc(buffer2,500*sizeof(int));
     free(buffer1);
     free(buffer3);
     getch();
     return 0;
    }
    #elif defined SECOND_DEMO
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    int main(void)
    {
     char *str;
     /*allocate memory for string*/
     str=(char *)malloc(10);
     if (str==NULL)
     {
      perror("malloc");
      abort();
     }
     else
     {
      /*copy "hello" to string*/
      strcpy(str,"hello");
      /*display string*/
      printf("String is %sn",str);
      /*free memory*/
      free(str);
     }
     getch();
     return 0;
    }
    #endif


    DEMO:perror
    perror( ) 用來將上一個函數發生錯誤的原因輸出到標准設備(stderr)。參數 s 所指的字符串會先打印出,後面再加上錯誤原因字符串。此錯誤原因依照全局變量errno 的值來決定要輸出的字符串。

    復制代碼 代碼如下:
    #include <stdio.h>
    #include <stdlib.h>   //perror包含在此文件中
    #include <conio.h>
    int main(void)
    {
        FILE *fp;
     fp=fopen("abc","r+");
     if (NULL == fp)
     {
      perror("abc");
     }
     getch();
     return 0;
    }


    output:
    abc: No such file or directory
    DEMO:

    復制代碼 代碼如下:
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void)
    {
     char *ptr;
     ptr=(char *)malloc(100);
     strcpy(ptr,"Hello");
     free(ptr);    //<span style="font-family: arial, 宋體, sans-serif; font-size: 13.63636302947998px; line-height: 24px; text-indent: 30px;"> ptr 所指的內存被釋放,但是ptr所指的地址仍然不變,原來的內存變為“垃圾”內存(不可用內存)</span>
    #if 1
     if (ptr!=NULL)    /*<span style="font-family: arial, 宋體, sans-serif; font-size: 13.63636302947998px; line-height: 24px; text-indent: 30px;"> 沒有起到防錯作用</span>*/
     {
      strcpy(ptr," world");
      printf("%sn",ptr);
     }
    #endif
     getch();
     return 0;
    }


    free(str)後指針仍然指向原來的堆地址,即你仍然可以繼續使用,但很危險,因為操作系統已經認為這塊內存可以使用,他會毫不考慮的將他分配給其他程序,於是你下次使用的時候可能就已經被別的程序改掉了,這種情況就叫“野指針”,所以最好free()了以後再置空
    str = NULL;
    即本程序已經放棄再使用他。
    何謂“野指針”,在這裡補充一下。
    野指針是指程序員或操作者不能控制的指針。野指針不是NULL指針,而是指向“垃圾”的指針。

    造成“野指針”的原因主要有
    1.指針變量沒有初始化,
    任何指針變量剛被創建時不會自動成為NULL指針,它的缺省值是隨機的,它會亂指一氣。在初始化的時候要麼指向合法的指針,要麼指向NULL。

    2.指針變量被free或delete之後,沒有設置為NULL。它們只是把指針所指的內存給釋放掉,但並沒有把指針本身干掉。通常會用語句if (p != NULL)進行防錯處理。很遺憾,此時if語句起不到防錯作用,因為即便p不是NULL指針,它也不指向合法的內存塊。上文DEMO則是這種情況。

    3.指針操作超越了變量的作用范圍。注意其生命周期。

    【下面是摘自論壇裡面的形象比喻,加深理解。】
    CRT的內存管理模塊是一個管家。  
    你的程序(簡稱“你”)是一個客人。  
    管家有很對水桶,可以用來裝水的。  
    malloc的意思就是“管家,我要XX個水桶”。  
    管家首先看一下有沒有足夠的水桶給你,如果沒有,那麼告訴你不行。如果夠,那麼登記這些水桶已經被使用了,然後告訴你“拿去用吧”。  
    free的意思就是說:“管家我用完了,還你!”。  
    至於你是不是先把水倒干淨才給管家,那麼是自己的事情了。--是不是清零。
      
    管家也不會將你歸還的水桶倒倒干清(他有那麼多水桶,每個歸還都倒干淨豈不累死了)。反正其他用的時候自己會處理的啦。  
    free之後將指針清零只是提醒自己,這些水桶已經不是我的了,不要再完裡面放水了,^_^  
    如 果free了之後還用那個指針的話,就有可能管家已經將這些水桶給了其他人裝飲料的了,你卻往裡面撒了泡尿。好的管家可能會對你的行為表示強烈的不滿, 殺了你(非法操作)--這是最好的結果,你知道自己錯了(有錯就改嘛)。一些不好的管家可能忙不過來,有時候抓到你作壞事就懲罰你,有時候卻不知道去那裡 了--這是你的惡夢,不知道什麼時候、怎麼回事情自己就死了。不管怎麼樣,這種情況下很有可能有人要喝尿--不知道是你的老板還是你的客戶 了.^_^。  
    所以啊,好市民當然是還了給管家的東西就不要再占著啦,.^_^。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved