1. 程式人生 > >使用new來創建動態數組

使用new來創建動態數組

delet order [ ] 編寫一個程序 語言 ddd new 移動 center

原文來自:http://book.51cto.com/art/201211/367161.htm

使用new來創建動態數組(1)

如果程序只需要一個值,則可能會聲明一個簡單變量,因為對於管理一個小型數據對象來說,這樣做比使用new和指針更簡單,盡管給人留下的印象不那麽深刻。通常,對於大型數據(如數組、字符串和結構),應使用new,這正是new的用武之地。例如,假設要編寫一個程序,它是否需要數組取決於運行時用戶提供的信息。如果通過聲明來創建數組,則在程序被編譯時將為它分配內存空間。不管程序最終是否使用數組,數組都在那裏,它占用了內存。在編譯時給數組分配內存被稱為靜態聯編(static binding),意味著數組是在編譯時加入到程序中的。但使用new時,如果在運行階段需要數組,則創建它;如果不需要,則不創建。還可以在程序運行時選擇數組的長度。

這被稱為動態聯編(dynamic binding),意味著數組是在程序運行時創建的。這種數組叫作動態數組(dynamic array)。使用靜態聯編時,必須在編寫程序時指定數組的長度;使用動態聯編時,程序將在運行時確定數組的長度。

下面來看一下關於動態數組的兩個基本問題:如何使用C++的new運算符創建數組以及如何使用指針訪問數組元素。

1.使用new創建動態數組

在C++中,創建動態數組很容易;只要將數組的元素類型和元素數目告訴new即可。必須在類型名後加上方括號,其中包含元素數目。例如,要創建一個包含10個int元素的數組,可以這樣做:

技術分享

new運算符返回第一個元素的地址。在這個例子中,該地址被賦給指針psome。

當程序使用完new分配的內存塊時,應使用delete釋放它們。然而,對於使用new創建的數組,應使用另一種格式的delete來釋放:

技術分享

方括號告訴程序,應釋放整個數組,而不僅僅是指針指向的元素。請註意delete和指針之間的方括號。如果使用new時,不帶方括號,則使用delete時,也不應帶方括號。如果使用new時帶方括號,則使用delete時也應帶方括號。C++的早期版本無法識別方括號表示法。然而,對於ANSI/ISO標準來說,new與delete的格式不匹配導致的後果是不確定的,這意味著程序員不能依賴於某種特定的行為。

總之,使用new和delete時,應遵守以下規則。

不要使用delete來釋放不是new分配的內存。

不要使用delete釋放同一個內存塊兩次。

如果使用new [ ]為數組分配內存,則應使用delete [ ]來釋放。

如果使用new [ ]為一個實體分配內存,則應使用delete(沒有方括號)來釋放。

對空指針應用delete是安全的。

現在我們回過頭來討論動態數組。psome是指向一個int(數組第一個元素)的指針。您的責任是跟蹤內存塊中的元素個數。也就是說,由於編譯器不能對psome是指向10個整數中的第1個這種情況進行跟蹤,因此編寫程序時,必須讓程序跟蹤元素的數目。

實際上,程序確實跟蹤了分配的內存量,以便以後使用delete [ ]運算符時能夠正確地釋放這些內存。但這種信息不是公用的,例如,不能使用sizeof運算符來確定動態分配的數組包含的字節數。

為數組分配內存的通用格式如下:

技術分享

使用new運算符可以確保內存塊足以存儲num_elements個類型為type_name的元素,而pointer_name將指向第1個元素。下面將會看到,可以以使用數組名的方式來使用pointer_name。

2.使用動態數組

創建動態數組後,如何使用它呢?首先,從概念上考慮這個問題。下面的語句創建指針psome,它指向包含10個int值的內存塊中的第1個元素:

技術分享

可以將它看作是一根指向該元素的手指。假設int占4個字節,則將手指沿正確的方向移動4個字節,手指將指向第2個元素。總共有10個元素,這就是手指的移動範圍。因此,new語句提供了識別內存塊中每個元素所需的全部信息。

現在從實際角度考慮這個問題。如何訪問其中的元素呢?第一個元素不成問題。由於psome指向數組的第1個元素,因此*psome是第1個元素的值。這樣,還有9個元素。如果沒有使用過C語言,下面這種最簡單的方法可能會令您大吃一驚:只要把指針當作數組名使用即可。也就是說,對於第1個元素,可以使用psome[0],而不是*psome;對於第2個元素,可以使用psome[1],依此類推。這樣,使用指針來訪問動態數組就非常簡單了,雖然還不知道為何這種方法管用。可以這樣做的原因是,C和C++內部都使用指針來處理數組。數組和指針基本等價是C和C++的優點之一(這在有時候也是個問題,但這是另一碼事)。稍後將更詳細地介紹這種等同性。

首先,程序清單4.18演示了如何使用new來創建動態數組以及使用數組表示法來訪問元素;它還指出了指針和真正的數組名之間的根本差別。

使用new來創建動態數組(2)

程序清單4.18 arraynew.cpp

技術分享

下面是該程序的輸出:

技術分享

從中可知,arraynew.cpp將指針p3當作數組名來使用,p3[0]為第1個元素,依次類推。下面的代碼行指出了數組名和指針之間的根本差別:

技術分享

不能修改數組名的值。但指針是變量,因此可以修改它的值。請註意將p3加1的效果。表達式p3[0]現在指的是數組的第2個值。因此,將p3加1導致它指向第2個元素而不是第1個。將它減1後,指針將指向原來的值,這樣程序便可以給delete[ ]提供正確的地址。

相鄰的int地址通常相差2個字節或4個字節,而將p3加1後,它將指向下一個元素的地址,這表明指針算術有一些特別的地方。情況確實如此。

使用new來創建動態數組