2014-07-19 56 views
2

我需要有一個動態的字符串數組,以便隨時可以擴展它。所以我想用malloc/realloc做到這一點。但每次我試圖運行它,我得到分段錯誤與下面的錯誤從Valgrind的:std :: string的指針數組

==13709== Use of uninitialised value of size 8 
==13709== at 0x4EEED9B: std::string::assign(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) 
==13709== by 0x400953: main (test.cpp:12) 
==13709== 
==13709== Invalid read of size 8 
==13709== at 0x4EEED9B: std::string::assign(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) 
==13709== by 0x400953: main (test.cpp:12) 

我的代碼看起來像這樣:

int main() 
{ 
    string* arr; 
    arr=(string*) malloc(5*sizeof(string)); 
    arr[0]="test1"; 
    arr[1]="test2"; 
    cout << arr[0] << arr[1] << endl; 
} 

我知道字符**,但它是一種一個痛苦的使用,所以我想使用字符串。有關如何使其工作的任何提示?

+7

你爲什麼不製作一個'std :: vector '? – CoryKramer

+5

只要使用'矢量',爲自己節省很多的痛苦。 –

+0

別人說什麼。如果你想知道爲什麼你的代碼不工作,這是因爲'std :: string'是一個類,'malloc'不會調用它的構造函數,所以你基本上試圖訪問未初始化的對象,這會導致運行時錯誤。作爲一個通用規則(在極少數情況下可以被破壞),你不應該將C風格的分配('malloc&free')與C++類(或者如果你想成爲純粹的代碼)混合使用。 – UnholySheep

回答

6

總結註釋:

malloc(5*sizeof(string))只會分配內存足夠大,以適應5 std::string秒。在使用對象之前,需要在分配內存之後初始化類類型對象(如std::string),這意味着構造對象。試圖使用未初始化的內存,就像它是一個有效的初始化的std::string對象一樣,會給你一個未定義的行爲。

在C++中,使用new運算符執行動態內存分配。也就是說,您的線路將被編寫爲arr = new string[5];。這爲5 std::string s分配空間並且也構建它們全部。他們然後準備好使用。

但是,在C++中,我們嘗試避免自己執行動態內存分配,因爲它會導致錯誤和不安全的代碼。相反,我們使用封裝這種行爲的類(通常是由標準庫提供的類)。在這種情況下,使用代表容器std::stringstd::vector<std::string>可以輕鬆地添加,刪除,調整大小等,而不必擔心手動動態分配。

爲了演示如何更好,這是,這是我會怎麼寫代碼:

int main() { 
    std::vector<std::string> arr = {"test1", "test2"}; 
    std::cout << arr[0] << arr[1] << std::endl; 
} 
1

我需要有一個字符串動態數組,這樣我就可以在 隨時展開。所以我想用malloc/realloc做到這一點。
[...]
任何提示如何使其工作?

只是使用std::vector<std::string>

這樣,所有的內存管理都會自動發生在「引擎蓋下」
它會讓你的代碼更容易閱讀和維護。

在現代C++(除非有沒有做一個堅強的理由),可以考慮使用便利STL容器類,像std::vector和字符串類,像std::string,而不是原料類似C的指針。

如果你想更多的字符串添加到您的載體,只要調用std::vectorpush_back()方法,以及新的空間將用於新的字符串進行,以及矢量正確更新。

而且vector的和string的析構函數你會自動釋放內存。

這是一個巨大的勝利原始malloc/free(或new[]/delete[])。