delete[]問題

http://topic.csdn.net/u/20080303/21/66dff809-84c3-4e9b-8d72-dea17a63fcdf.html

通常在delete[]一個數組時,編譯器要按順序作如下兩件事情:


 1. 對每個數組元素調用析構函數
 2. 釋放對象數組所佔內存

注意這是彼此獨立的兩步.

在第2步.編譯器只需簡單地把數組首地址告訴操作系統,操作系統內部有內存申請情況的記錄(每個申請內存段的首地址,長度,etc..),因此會正確地釋放掉內存.注意整個數組所佔內存是一次釋放掉的,而不是每個元素釋放一次.事實上,在這一步編譯器無需知道數組元素個數.

當然在第1步確實需要知道元素個數.因此如樓主所說,編譯器會把元素個數放在分配的那塊內存的前面,結構如下所示
  n object1 object2 ... objectn

不要把這個n和數組內存長度混淆起來.前者是編譯器管理的,後者是操作系統管理的.(如果知道對象的size,是可以從後者計算出前者.遺憾的是,操作系統沒有API提供所申請的內存段的長度,編譯器只好自己記錄)  

要注意的是,如果數組元素沒有顯式構造函數(例如char),那麼編譯器就無需作第1步了.在這種情況下,編譯器根本不需要知道數組個數,因此就偷懶不再在數組前面放元素個數n了.樓主的疑問就是這個緣故(你換一個有構造函數的類就會看到這個傳說中的n了).看來C++的一個原則是能省就省

要注意的是,如果數組元素沒有顯式構造函數(例如char),那麼編譯器就無需作第1步了.在這種情況下,編譯器根本不需要知道數組個數,因此就偷懶不再在數組前面放元素個數n了.樓主的疑問就是這個緣故(你換一個有構造函數的類就會看到這個傳說中的n了).看來C++的一個原則是能省就省


一個例子:(運行環境vs2008)

#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>


class A
{
public:
    int a;
    int b;
    A():a(0), b(1)
    {

    }
    ~A()
    {

    }
};

int main()
{
    A* pA = new A[10];
    int* p = (int*)pA;
    p--;
    cout<<*p<<endl;


    int* pArry = new int[10];
    p = (int*)pArry;
    p--;
    cout<<*p<<endl;


    delete []pArry;
    delete []pA;
    
    getchar();
	return 0;
}


在debug版本的時候,分別查看pA內存和pArry內存信息如圖

 pA內存信息

pArry內存信息

從上面兩張圖片可以看到,在pA地址前面四個字節正好是pA對象數組的個數10(0a 00 00 00),而pArry地址前面卻沒有這樣的一個數,同時,我們還發現在pA佔用8*10 = 80個字節,這個數值是記錄在pA地址向前五個int(藍色方框標註)的地方(54 00 00 00),比80正好多了一個表示pA對象個數的4個字節,總共84個字節,而pArry在pArry地址向前四個int正好也是pArry數組的大小80的值。


如果上述代碼中A類沒有編寫析構函數,則我們會發現pA地址前面字節不是10這個表示數組大小的值,這是因爲此時編譯器沒有幫你實現析構函數(什麼情況會有呢?在對象基類有定義析構函數或者成員對象有析構函數的時候,編譯器會幫你實現析構函數),也就不需要知道數組大小的緣故。

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