free 與 delete


1. delete 用於釋放 new 分配的空間,free 有用釋放 malloc 分配的空間
2. delete [] 用於釋放 new [] 分配的空間
3. delete 釋放空間的時候會調用 相應對象的析構函數
     順便說一下new在分配空間的時候同時會調用對象的構造函數,對對象進行初始化,使用malloc則只是分配內存
4. 調用free 之前需要檢查 需要釋放的指針是否為空,使用delete 釋放內存則不需要檢查指針是否為NULL
5. free 和 delete 不能混用,也就是說new 分配的內存空間最好不要使用使用free 來釋放,malloc 分配的空間也不要使用 delete來釋放
     舉個例子,<string.h>里通常有個strdup函數,它得到一個char*字符串然后返回其拷貝:
     char * strdup(const char *ps); // 返回ps所指的拷貝
     在有些地方,c和c++用的是同一個strdup版本,所以函數內部是用malloc分配內存。這樣的話,一些不知情的c++程序員會在調用strdup后忽視了必須對   strdup返回的指針進行free操作。為了防止這一情況,有些地方會專門為c++重寫strdup,並在函數內部調用了new,這就要求其調用者記得最后delete。你可以想象,這會導致多么嚴重的移植性問題,因為代碼中strdup以不同的形式在不同的地方之間顛來倒去。
 
補充一個問題,free和delete 是如何知道需要釋放的內存塊的大小的?
     
     在調用malloc或new 分配內存空間的時候,實際分配的空間會比程序員申請的空間要大。實際分配的內存空間前面有一部分空間用於保存所分配內存的大小,校驗和等信息。當分配函數返回時,將會返回實際可操作的地址(也就是實際分配空間加上前面用於記錄分配信息的空間之后的地址)。下面舉個例子,例子通過破壞 new 返回地址的前面四個字節的數據導致內存空間釋放出問題。如果不破壞前面的數據則不會出現內存不能釋放的情況。
#include <stdio.h>
#include <new>
#include <iostream>
#include <stdlib.h>
#include <string.h>

int main()
{
    int *p = NULL,*p1=NULL;
    int i;
    //p = (int *) malloc(10 * sizeof(int));
    p = new int[10];

    memset(p,0,sizeof(int) * 10);
    for(i=0;i<10;i++)
        printf("P:%d\t",p[i]);
    printf("addr p: %x\n",p);

    *(p-1) = 2; //如果不注釋掉這一行則程序運行不正確
    *(p+11) = 3;
    printf("addr before p: %x\n",p+11);
    printf("%x %x\n",*(p-1),*(p+11));

    //free(p);
    delete [] p;
    printf("free successfully! \n");
    return 0;
}

當注釋了*(p-1) = 2之后運行結果為:

當不注釋*(p-1) =2 這一行時,結果為:


免責聲明!

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



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