2014-04-07 37 views
-2

我必須做某種項目,並且我被卡住了。我得到一個bad_alloc錯誤。我檢查了很多次代碼,嘗試谷歌一些解決方案,但仍然沒有,這就是爲什麼我寫在這裏。事情是程序正常運行,但在任務管理器,他的內存使用率提高到2GB(這是限制我知道),然後它崩潰。程序需要檢查分配空間和複製變量的時間。以下是部分代碼:創建20k陣列時的bad_alloc

class Table 
{ 
    int *tablica; 
    int size; 

public: 
Table() 
    { 
     tablica = NULL; 
     size = 0; 
    } 

~Table() 
    { 
     delete tablica; 
     size = 0; 
    } 

int *push_back(int val) 
    { 
     int *temp = new int[size]; 
     if(size % 10 == 0) 
     { 
      for(int i = 0; i < size; i++) 
       temp[i] = tablica[i]; 
      tablica = new int[size + 10]; 
      for(int i = 0; i < size; i++) 
       tablica[i] = temp[i]; 
     } 
     tablica[size] = val; 
     size++; 
     delete []temp; 
     return tablica; 
    } 

void test() 
    { 
      LONGLONG measure[100][6]; 
     LARGE_INTEGER performanceCountStart, performanceCountEnd; 
     int cpy_tab [20000]; 

     for(int j = 0; j < 100; j++) 
     { 
      for(int i = 0; i < 20000; i++) 
       cpy_tab[i] = rand() % 10000 - 10000; 

      performanceCountStart = startTimer(); 
      for(int i = 0; i < 500; i++) 
       { 
        push_back(cpy_tab[i]); 
       } 
      performanceCountEnd = endTimer(); 
    measure[j][0] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][0]<<endl; 

      delete []tablica; 
      size = 0; 

      performanceCountStart = startTimer(); 
      for(int i = 0; i < 2000; i++) 
      { 
       push_back(cpy_tab[i]); 
      } 
      performanceCountEnd = endTimer(); 
    measure[j][1] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][1]<<endl; 

      delete []tablica; 
      size = 0; 


      performanceCountStart = startTimer(); 
      for(int i = 0; i < 4000; i++) 
      { 
       push_back(cpy_tab[i]); 
      } 
      performanceCountEnd = endTimer(); 
    measure[j][2] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][2]<<endl; 

      delete []tablica; 
      size = 0; 


      performanceCountStart = startTimer(); 
      for(int i = 0; i < 8000; i++) 
      { 
       push_back(cpy_tab[i]); 
      } 
      performanceCountEnd = endTimer(); 
    measure[j][3] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][3]<<endl; 

      delete []tablica; 
      size = 0; 


      performanceCountStart = startTimer(); 
      for(int i = 0; i < 14000; i++) 
      { 
       push_back(cpy_tab[i]); 
      } 
      performanceCountEnd = endTimer(); 
    measure[j][4] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][4]<<endl; 

      delete []tablica; 
      size = 0; 

      performanceCountStart = startTimer(); 
      for(int i = 0; i < 20000; i++) 
      { 
       push_back(cpy_tab[i]); 
      } 
      performanceCountEnd = endTimer(); 
    measure[j][5] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; 
      cout<<j<<"."<<measure[j][5]<<endl; 

      delete []tablica; 
      size = 0; 
     } 
    } 

解決這個問題的任何想法都是值得的!

+1

你不能給我們提供一個簡短的例子嗎?嵌套for循環出了什麼問題?真的有必要再次複製和粘貼這麼多代碼嗎? – xmoex

+1

如果您懷疑有內存泄漏,請通過'valgrind'運行並查看另一端出現的內容。此外,請嘗試將示例的大小減小到可以重現問題的最小可編譯示例。你會經常發現,在試圖隔離這個最小的例子時,你已經發現了答案。 – merlin2011

+0

請先調試並縮小您的問題。同樣使用像valgrind這樣的內存泄漏檢測器會是一個好主意。很可能你在某處泄漏,消耗的內存意外地累積。 –

回答

2

你肯定漏水,而且很可能破碎的記憶,當你這樣做:

int *temp = new int[size]; 
    if(size % 10 == 0) 
    { 
     for(int i = 0; i < size; i++) 
      temp[i] = tablica[i]; 
     // Should free tablica here 
     tablica = new int[size + 10]; 
     for(int i = 0; i < size; i++) 
      tablica[i] = temp[i]; 
    } 

首先,你分配一個臨時的(即使你不需要),這是size元素,那麼你分配一個size+10元素數組,它不被釋放。

我建議你使用第二個變量來記錄容量,並在每次容量時加倍容量。這樣,您不需要2000次分配將陣列增長到20000個元素,但是需要15次重新分配(和複製)。

+0

我不認爲有泄漏 - 擴展數組(有10個附加元素)在'tablica'指針中被跟蹤,它在'test()'中的各個點被刪除,並且在dtor中被刪除(不正確)。但是,我會說管理'tablica'指針的代碼相當混亂。 –

+2

它在循環後被刪除,但不在循環中。因此,在一個由1000個元素組成的循環中,進行了100次分配,循環後只有一次刪除。 –

+0

你說得對 - 我看到我現在想念的東西。 –

1

你並沒有完全展示你如何使用Table類,但你可能會破壞堆。

test()函數重複推送數據到tablica然後做一個delete [] tablica再做一輪推。

然而,當test()函數刪除tablica最後一次,它不設置poitner到NULL,並Table desctuctor樣子:

~Table() 
{ 
    delete tablica; 
    size = 0; 
} 

因此,這將繼續前進,再刪除該指針導致堆被損壞。請注意,~Table()中的delete操作應該是delete [] tablica;

此外,請注意,在push_back()test()和dtor函數中管理tablica指針會造成混亂。

1

因爲你正在泄漏tablica內存。 之前

tablica = new int[size + 10]; 

添加一行

delete []temp; 

所有的一切都將被罰款。

在每次push_back調用中,您都會不必要地分配內存並刪除它。相反,如果條件分配內存並釋放內部空間。

+0

嗯 - 這會使得難以將temp數組中的數據複製到新的'tablica'數組中。 –

+1

@MohitJain:你的意思是'刪除[] tablica',就像我在回答中寫的那樣。 –

+0

@MatsPetersson是墊你說得對。我花了很長時間來輸入信息,當我提交時,我結束了重複的建議:( –