簡體   English   中英

調整數組大小 - 兩個執行塊之間的差異?

[英]Resizing Arrays - Difference between two execution blocks?

我有一個函數,當嘗試添加元素時,它會生成一個數組。 哪個執行塊更好或更快?

我認為我的第二個塊(注釋掉了)可能是錯誤的,因為在我的陣列加倍之后我會回去並指向原始陣列。

在創建數組時,編譯器是否在內存中尋找一個完全適合的連續塊? (在堆棧/堆上?我不完全理解哪些,盡管對我來說重要的是學習它與實際問題無關。)

如果是這樣,這是否意味着使用第二個塊可能會通過覆蓋相鄰的內存來覆蓋其他信息? (因為原來會使用20個相鄰的內存塊,而后者是40個。)

或者它只是意味着我的數組中的元素的位置將被拆分,導致性能不佳?

void Grow()
{
  length *= 2; // double the size of our stack

  // create temp pointer to this double sized array
  int* tempStack = new int[length];

  // loop the same number of times as original size
  for(int i = 0; i < (length / 2); i++) 
  {
    // copy the elements from the original array to the temp one
    tempStack[i] = myStack[i]; 
  }

  delete[] myStack; //delete the original pointer and free the memory
  myStack = tempStack; //make the original point to the new stack

  //Could do the following - but may not get contiguous memory block, causing
  // overwritten >data
#if 0
  int* tempStack = myStack; //create temp pointer to our current stack
  delete[] myStack; //delete the original pointer and free memory
  myStack = new int[length *= 2]; //delete not required due to new?
  myStack = tempStack;
#endif
}

第二個塊根本無法實現你想要的。

當你這樣做

myStack = new int[length *= 2];

然后系統將返回一個指針,指向分配新的較大數組的位置。

然后你將myStack重新分配到舊位置(你已經取消分配!),這意味着你指的是未分配的內存(壞!)並且你丟失了指向你剛剛分配的新內存的指針(也不好!)

編輯 :為了澄清,您的數組將在堆上分配。 此外,較大的數組分配( new int[foo] )返回的(新)指針將是一個連續的內存塊,就像舊的一樣,可能位於不同的位置。 除非你走出界限,否則不要擔心“覆蓋”記憶。

由於這個順序,你的第二個塊是不正確的:

int* tempStack = myStack; //create temp pointer to our current stack
delete[] myStack; //delete the original pointer and free memory

tempStack和myStack都只是指向同一塊內存的指針。 當您刪除第二行中的[]指針時,您無法再通過任一指針訪問該內存。

使用C ++內存管理,如果要增長數組,則需要先創建一個新數組,然后再刪除舊數組並自行復制值。

也就是說,既然你正在使用POD,你可以使用C風格的內存管理,它支持通過realloc直接增長數組。 如果內存管理器意識到它可以在不移動緩沖區的情況下增加緩沖區,那么這可能會更高效一些(盡管如果它不能增加緩沖區,它將會回退到你在第一個塊中增長數組的方式)。

C風格的內存管理只適用於POD陣列。 對於非POD,您必須執行create new array / copy / delete舊數組技術。

這並不完全回答你的問題,但你不應該做任何一個。 通常應該避免使用new[]delete[]來支持使用std::vector new[]很難使用,因為它需要顯式內存管理(如果在復制元素時拋出異常,則需要捕獲異常並刪除數組以避免內存泄漏)。 std::vector為您處理這個問題,自動增長,並且很可能有一個由供應商調整的有效實現。

使用顯式數組的一個參數是擁有一個可以傳遞給C函數的連續內存塊,但是對於任何非病態實現也可以用std::vector完成(並且下一版本的C ++標准將需要所有符合要求的實現以支持)。 (供參考,請參閱ISO C ++標准委員會前召集人Herb Sutter的http://www.gotw.ca/publications/mill10.htm 。)

反對std::vector另一個論點是std::vector<bool>的奇怪之處,但如果你需要它,你可以簡單地使用std::vector<char>std::vector<int> (見: http//www.gotw.ca/publications/mill09.htm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM