2016-12-06 192 views
1

我正在學習C++閱讀Stroustrup的書,在我看來,這個主題不是很清楚(數組)。從我所瞭解C++有(如德爾福)兩種陣列:動態和靜態數組

靜態數組被聲明如下

int test[3] = {10,487,-22}; 

動態數組被稱爲矢量

std::vector<int> a; 

a.push_back(10); 
a.push_back(487); 
a.push_back(-22); 

我已經看到有關這方面的答案(並且裏面有很多線條和概念),但他們沒有向我闡明這個概念。


從我所瞭解vector小號佔用更多的內存,但他們可以改變它們的大小(動態,其實)。數組在編譯時具有固定的大小。

在章節Stroustrup說,矢量是安全的,而數組不是,但沒有解釋原因。我確實相信他,但爲什麼?記憶的位置是否與安全有關? (堆/棧)

我想知道爲什麼我使用載體,如果他們是安全的。

+0

這是一個非常廣泛的討論,如果你問使用std :: vector,數組和指針的優點和陷阱。 –

+0

在我的代碼中,我將使用向量總是和數組,只有當我發現有人在舊版本中使用它們時。但我想知道爲什麼 –

+0

std :: vector是一個很好的機器,已經接管了以前用數組解決的大多數任務。你會想研究std :: vector是如何設計的以及爲什麼。這包括資源管理(3/5規則)以及算法行爲。 –

回答

3

數組不安全的原因是內存泄漏。

如果聲明一個動態數組

int * arr = new int[size] 

和你不這樣做刪除[] ARR,則存儲器保持未清除的,這就是所謂的內存泄漏。需要注意的是,任何時候當你在C++中使用new這個詞時,都必須有一個刪除的地方來釋放這個內存。如果你使用malloc(),那麼應該使用free()。

http://ptolemy.eecs.berkeley.edu/ptolemyclassic/almagest/docs/prog/html/ptlang.doc7.html

這也是非常容易去出界在陣列中,例如,在比其尺寸大-1的索引插入的值。使用矢量,可以根據需要push_back()儘可能多的元素,矢量將自動調整大小。如果你有一個大小爲15的數組,你試圖說arr [18] = x, 然後你會得到一個分段錯誤。該程序將編譯,但當它達到一個聲明將其置於數組邊界之外時將會崩潰。

一般來說,當你有大的代碼時,數組很少使用。幾乎在所有方面,矢量在客觀上都非常優越,所以使用數組變得毫無意義。

編輯:正如保羅·麥肯齊在評論中指出,走出去的數組邊界不保證分段錯誤,而是不確定的行爲,要由編譯器來確定發生了什麼

+0

他們需要更多的空間是的,但總的來說,我應該更喜歡矢量。我想我已經理解了「安全」在哪裏:)也可以用很多有用的方法實現向量;陣列是「古老的」,可用於C復古兼容性 –

+0

這是事實。向量使用更多的存儲空間,但與載體帶來的安全/效率優勢相比,這是模糊的。 –

+2

@ConnorSchwinghammer - *如果你有一個大小爲15的數組,並且你試圖說arr [18] = x,那麼你會得到一個分段錯誤* - 如果你使用'[]'向量跳出界限(是的,調試Visual C++運行時會檢查,而不是發佈版本),你不能保證出現分段錯誤。所以,當你走出界限時,你基本上可能會遇到與使用常規數組相同的未定義行爲。然而'vector'有'at()'函數,這保證瞭如果索引超出範圍,就會拋出一個'std :: out_of_range'異常。所以也許你應該修改你的答案? – PaulMcKenzie

-4

我可以看到的一個安全性是,你不能訪問不存在的向量中的東西。

我的意思是,如果你push_back只有4個元素,並且你試圖訪問索引7,那麼它會拋出一個錯誤。但在陣列中並沒有發生。

總之,它阻止你訪問損壞的數據。

編輯:

程序員必須比較vector.size()指數拋出一個錯誤。它不會自動開心。一個人必須自己做。

+0

在大多數情況下這是不真實的。 –

+0

@CaptainGiraffe,我的意思是像之前使用任何索引號,我們可以將它與vector.size()進行比較,並且我們可以決定它是否超出限制。 –

+0

任何合理使用數組的情況也是如此。 –

2

讓我們以從文件讀取數字的情況。
我們不知道文件中有多少個數字。

要聲明一個數組來保存數字,我們需要知道容量或數量,這是未知的。我們可以選擇一個數字,如64.如果文件的數量超過64,我們將開始覆蓋數組。如果文件少於64個(如16),我們浪費內存(不使用48個插槽)。我們需要的是動態調整容器(數組)的大小。

要動態調整數組的容量,必須創建一個新的更大的數組,然後複製元素並刪除舊數組。

std::vector將根據需要調整其容量。它爲你處理動態的內存分配。

另一方面是將容器傳遞給函數。有了數組,你需要傳遞數組和容量。用std::vector,你只需要傳遞向量。可以查詢矢量對象的容量。