2014-01-20 42 views
1

我需要將std :: vector轉換爲數組。我嘗試用這個簡單的代碼:如何將矢量轉換爲數組並訪問它

#include <vector> 
#include <iostream> 

using namespace std; 

int main(){ 

vector<double> v; 
double* a = &v[0]; 


for (int i=0; i<10; i++) 
v.push_back(i); 

cout<<"Value -V- 9: "<<v[9]<<endl; 
cout<<"Value -a- 9: "<<a[9]<<endl; //Gives me segmentation fault error 

return 0; 
} 

我在另一個討論閱讀這樣一個向量轉換成數組,但現在我還需要訪問我的數組的單個元素(這樣編譯器給我的錯誤分段故障)。我在C++中很新,也許這種方法是完全錯誤的。任何人都可以幫我解決這個問題嗎?

+1

您正在'main()'的第二行調用未定義的行爲。您正在請求您的向量中尚不存在的元素的地址。在插入循環後移動第二行*。 – WhozCraig

+0

相當明顯:) txs WhozCraig – zzari

+1

@WhozCraig更糟的是,它不是唯一的UB,事實上我不認爲它是重要的。插入後指向矢量元素的指針會失效,並且可能是導致該問題的原因。 – 2014-01-20 16:17:41

回答

1

首先,您應該瞭解std :: vector如何工作:它是一個自擴展數組,它可以在需要時重新分配其內部存儲。 獲得一個指向數組內部的一個正確的方法是調用的std ::矢量::數據成員(僅適用於C++ 11):

double * a = v.data(); 

注意,該指針是有效的只有等到你修改向量。 爲了以防萬一,這裏的「轉換」並不意味着真正的轉換,向量不會被修改,也不會創建新的數組。只接收到存儲在std :: vector中的數據的指針。

+2

在C++ 11之前,您可以通過&(v [0])來獲取數據指針。 std :: vector(幾乎?)必須作爲一個連續的數組來實現,而且事實上它在我意識到的所有標準庫中。 – Eloff

+0

這篇文章部分不正確。對矢量現有元素的修改不會使先前由&v [0]返回的地址無效。調用成員函數來獲取地址對於使用數據成員來說或多或少是安全的,因爲如果內存未被分配,它甚至不會引發異常。 – shawn1874

+0

@ shawn1874:你說得對,我似乎是指「修改矢量大小」的意思。調用成員函數更具可讀性,看起來並不像利用實現細節(&v [0]不是「利用實現細節」,因爲C++ 11向量必須作爲連續數組來實現,但它看起來像,至於我)。 – lisyarus

0
double* a = &v[0]; 

答案已經張貼在評論,但底線是,你是因爲在程序矢量沒有數據內的點初始化的地址無效。爲了讓你的例子工作,你需要在循環完成後將指針設置爲a。插入過程中可能會重新分配矢量,因此插入後不能相信原始指針。在這種情況下,永遠不會指向任何有效的東西。

通常情況下,獲取元素地址的能力與需要原始指針的舊接口結合使用。如果您正在編寫新的C++代碼,最好使用容器的接口來獲取數據。優先於原始指針的迭代器,並閱讀有關如何通過某種操作使迭代器失效的信息。