2013-03-31 85 views
1

我想調整動態分配的字符串數組的大小;這是代碼!調整動態字符串數組的大小

void resize_array() { 
    size_t newSize = hash_array_length + 100; 
    string* newArr = new string[newSize]; 

    fill_n(hash_array,newSize,"0"); //fills arrays with zeros 

    memcpy(newArr, hash_array, hash_array_length * sizeof(string)); 

    hash_array_length = newSize; 
    delete [] hash_array; 
    hash_array = newArr; 
} 

不幸的是,它不工作,並給出了分段錯誤。任何想法爲什麼?這基本上是一個線性探測哈希表,其中的元素插入任何有0的位置,因此我使用fill_n來填充新創建的數組0。請幫忙嗎?

+1

您能告訴我們您在這裏使用哪種語言以及在哪一行發生分段錯誤?謝謝。 – Simon

+0

我使用的語言是C++,我無法確定發生分段錯誤的行,我使用dev-C++作爲編譯器,我想調試器出現問題。 –

+1

使用['std :: string :: empty()'](http://en.cppreference.com/w/cpp/string/basic_string/empty)而不是填充來測試未使用的條目會不會更簡單並測試一個魔術值「0」? – Blastfurnace

回答

4
memcpy(newArr, hash_array, hash_array_length * sizeof(string)); 

此行是極其危險的,的std :: string是不是一個普通的舊數據類型, 你不能確保的memcpy能夠正確初始化它,它可能會導致 未定義的行爲,一個最C++(或編程)的令人討厭的行爲。

此外,還有更好的和更安全的(在大多數的次)溶液中以產生 C++中的動態字符串數組,只需使用矢量

//create a dynamic string array with newSize and initialize them with "0" 
//in your case, I don't think you need to initialize it with "0" 
std::vector<std::string> newArr(newSize, "0"); 

如果hash_array具有相同的類型newArr( std :: vector) 複製它的方式非常簡單。

C++ 98

std::copy(hash_array.begin(), hash_array.end(), newArr.begin()); 

C++ 11

std::copy(std::begin(hash_array), std::end(hash_array), std::begin(newArr)); 

更好地治療C++作爲一種新的語言,它有太多東西是從C不同。 此外,還有很多像樣的免費IDE,像code :: blocks和QtCreator devC++是一個幾乎死亡的項目。

如果您不熟悉C++,C++ primer 5是一本好書。

+0

這樣做會和前面的memcpy行一樣嗎?我真的從來沒有做過C,從C++開始。 –

+0

不,這段代碼只創建動態字符串數組,並用「0」初始化它。我不知道如何在知道hash_array的類型之前將hash_array複製到newArr。 – StereoMatching

1

如果string實際上是std::string(並且可能即使不是),那麼這將會崩潰。您正在創建一個新的字符串數組,將舊的字符串類複製到頂部,然後釋放舊的字符串。但是,如果字符串類包含分配內存的內部指針,則這將導致雙重空閒,因爲您所做的只是複製內部指針 - 而不是創建新的內存分配。

想想這樣;想象一下你有以下類:

class foo 
{ 
    char* bar; 

    foo() { bar = malloc(100); } 
    ~foo() { free(bar); 
}; 

foo* ptr1 = new foo; 
foo* ptr2 = new foo; 
memcpy(ptr2, ptr1, sizeof(foo*)); 
delete ptr1; 

在這一點上,ptr2->bar指向相同的內存ptr1->bar沒有,但ptr1和其持有的內存已經釋放

最好的解決辦法是使用std::vector,因爲這會自動處理大小調整,並且根本不需要擔心複製數組。但是,如果你想與你目前的做法持續下去,您需要更改memcpy調用以下:

for (int i = 0; i < hash_array_length; ++i) 
{ 
    newArr[i] = hash_array[i]; 
} 

而不是僅僅複製內存,這將調用類的拷貝構造函數,並對其內容進行適當的複製。

+0

非常感謝!這似乎很有幫助,而且確實很有意義! :d –

0

我懷疑罪魁禍首是memcpy電話。 string是通過指針管理char數組的複雜類型(就像你現在正在做的那樣)。通常情況下,複製字符串是使用賦值運算符完成的,該運算符對於字符串也複製其自己的數組但memcpy只是複製每個字節的指針,而delete []也會刪除由字符串管理的數組。現在另一個字符串使用已刪除的字符串數組,即BAAAD。

您可以使用std :: copy而不是memcpy,或者更好的方法是使用std :: vector,這可以解決大部分動態內存處理問題。