這里描述的是一種很常見的情況:當你在某個緩存中存儲數據時,經常需要在運行時調整該緩存的大小,以便能容納更多的數據。傳統的內存再分配技術非常繁瑣,而且輕易出錯:在 C 語言中,一般都是每次在需要擴充緩存的時候調用 realloc()。在 C++ 中情況更糟,你甚至無法在函數中為 new 操作分配的數組重新申請內存。你不僅要自己做分配處理,而且還必須把原來緩存中的數據拷貝到新的目的緩存,然后釋放先前數組的緩存。本文將針對這個問題提供一個安全、簡易并且是自動化的 C++ 內存再分配技術——即使用 STL 的 vector。
用 STL vector 對象取代內建的數組來保存獲取的數據,既安全又簡單,并且是自動化的。
進一步的問題分析
在提出解決方案之前,我先給出一個具體的例子來說明 C++ 重新分配內存的弊病和復雜性。假設你有一個編目應用程序,它讀取用戶輸入的 ISBNs,然后將之插入一個數組,直到用戶輸入 0 為止。假如用戶插入的數據多于數組的容量,那么你必須相應地增加它的大小:
#include <iostream> using namespace std;
int main() { int size=2; // 初始化數組大小;在運行時調整。 int *p = new int[size]; int isbn; for(int n=0; ;++n) { cout<< "enter an ISBN; PRess 0 to stop "; cin>>isbn; if (isbn==0) break; if (n==size) // 數組是否到達上限? reallocate(p, size); p[n]=isbn; // 將元素插入擴容的數組 } delete [] p; // 不要忘了這一步! } 注重上述這個向數組插入數據的過程是多么的繁瑣。每次反復,循環都要檢查緩存是否達到上限。假如是,則程序調用用戶定義的函數 reallocate(),該函數實現如下:
#include <algorithm> // for std::copy
int reallocate(int* &p, int& size) { size*=2; // double the array''s size with each reallocation int * temp = new int[size]; std::copy(p, p+(size/2), temp); delete [] p; // release original, smaller buffer p=temp; // reassign p to the newly allocated buffer } reallocate() 使用 STL std::copy() 算法對緩存進行合理的擴充——每次擴充都放大一倍。這種方法可以避免預先分配過多的內存,從量上減少需要重新分配的內存。這個技術需要得到充分的測試和調試,當初學者實現時尤其如此。此外,reallocate() 并不通用,它只能處理整型數組的情形。對于其它數據類型,它無能為力,你必須定義該函數額外的版本或將它模板化。幸運的是,有一個更巧妙的辦法來實現。