2013-04-16 237 views
3

我正在編寫一個準數據庫。爲什麼我不能打印工資?

我有一個類對:

class Pair{ 
    MyString m_key; 
    Data* m_data; 
} 

然後,該方法的AddItem構成一對,並添加到數據庫中。

Data Ivanov(1, 10, "Manager", 100000); 
Data Petrov(2, 20, "Manager", 200000); 
MyString* employee0 = new MyString("Ivanov"); 
MyString* employee1 = new MyString("Petrov"); 
bd.AddItem(employee0, &Ivanov); 
bd.AddItem(employee1, &Petrov); 

數據庫本身監視元素的數量和容量。 Bd類{ private: int m_size; int m_capacity; Pair ** ar; ... }

如果我們添加一個項目,數據庫會在容量溢出時延長。 如果我們刪除一個項目,會出現一個空的單元格,可能在將來使用。 這樣做是爲了不將堆碎成太多。

void Bd:: AddItem(MyString* key, Data* data){ 
    if (m_size < m_capacity){ 
     *ar[m_size+1] = Pair(key, data); 
    } 
    else{ 
     if (m_size == 0){ 
      ar = new Pair*[++m_size]; 
      m_capacity++;   
      ar[0] = new Pair(key, data); 
      stop 
     } 
     else{ 
      Pair** tmp = new Pair*[++m_size]; 
      m_capacity++; 
      memcpy(tmp, ar, m_size * sizeof(Pair*)); 
      delete[] ar; 
      ar = tmp; 
      ar[m_size-1] = new Pair(key, data); 
      stop 
     } 
    } 
} 


void Bd::RemoveItem(const char* a_key){ 
    Pair** tmp_ar = this->get_ar(); 
    for (int i = 0; i < m_size; i++){  
     Pair* tmp_key = tmp_ar[i]; 
     MyString* tmp_my_string= (*tmp_key).get_m_key(); 
     const char* tmp_str = (*tmp_my_string).GetString(); 
     if (strcmp(tmp_str, a_key) == 0){ 
      delete ar[i];   
      for (int j = i; j < m_size-1; j++){ 
       *ar[j] = *ar[j+1]; 
      } 
      delete ar[m_size-1]; 
      m_size--; 
      break; 
     } 
     stop 
     if (i == (m_size-1)){ 
      cout << "No such person." <<endl;   
     } 
    } 
    stop 
} 

那麼,現在我要使用bd。

cout << bd; 
bd.Print("Ivanov"); 
bd.Print("Petrov"); 

它完美地工作。它可以打印整個數據庫或任何元素。

然後,我刪除先生伊萬諾夫。 bd.RemoveItem(「Ivanov」);

現在我有問題,要麼這個:

bd.Print("Petrov"); 
cout << bd; 

我有類數據的印刷方法。

void Data:: print_info(){ 
    cout << "Sex: " << this->getSex() << ", age: " << age <<", position: " << position <<", salary: "; 
    cout << salary << endl; 
} 

我有特製的第二COUT,因爲這是我有煩惱。 工資雖然在範圍內清晰可見,但卻造成了整個問題。 請看看這張照片:

enter image description here

如果我讓了一步,我得到的錯誤關於堆的腐敗。 輸出窗口顯示:HEAP:免費堆塊296b30在296b58修改後釋放

您能否幫我理解爲什麼我無法打印此薪水?

+2

我在代碼中看不到任何貓... –

+0

通過使用免費的數據庫(如SQLite或MySql),而不是編寫自己的代碼,你會做得更好。 –

+0

嘗試這種改變'* ar [j] = * ar [j + 1];'to'ar [j] = ar [j + 1];'RemoveItem'' – stardust

回答

0

我看到AddItem()以下問題:

void Bd:: AddItem(MyString* key, Data* data){ 
    if (m_size < m_capacity){ 
     *ar[m_size+1] = Pair(key, data); 
    } 

如果m_size小於m_capacity,你添加一個新的項目,但不增加m_size

else{ 
     if (m_size == 0){ 
      ar = new Pair*[++m_size]; 
      m_capacity++;   
      ar[0] = new Pair(key, data); 
      stop 
     } 

我假設你的意思是要檢查m_capacity爲0。

 else{ 
      Pair** tmp = new Pair*[++m_size]; 
      m_capacity++; 
      memcpy(tmp, ar, m_size * sizeof(Pair*)); 
      delete[] ar; 
      ar = tmp; 
      ar[m_size-1] = new Pair(key, data); 
      stop 
     } 

memcpyar,它的尺寸爲m_size你增加m_size前先複製,但現在有一個大小的m_size-1,讓您複製過去的數組的末尾。

而且在RemoveItem()了以下問題:

if (strcmp(tmp_str, a_key) == 0){ 
    delete ar[i];   
    for (int j = i; j < m_size-1; j++){ 
     *ar[j] = *ar[j+1]; 
    } 
    delete ar[m_size-1]; 
    m_size--; 
    break; 
} 

delete ar[m_size-1]被刪除你剛剛搬到ar[m_size-2]的項目。你不想刪除這個。

我在想這個刪除可能是你的問題的一部分。具體來說,我認爲以下2個變化將有助於:

  1. 在評論中提到*ar[j] = *ar[j+1]行更改爲ar[j] = ar[j+1]
  2. 擺脫delete ar[m_size-1];一行。與ar換行一樣,你肯定不想要這個。

這不會解決所有問題,但它會確保你沒有試圖打電話給他print_info()方法之前刪除Petrov

+0

我同意關於m_size的一開始。至於最後一段,我真的想刪除這個,因爲我已經做了一個副本(* ar [j] = * ar [j + 1];)。那麼,這一切都很好,但它無法理解爲什麼我不能打印在範圍內可以看到的薪水。 – Trts

+0

我同意。我有一些擔心,刪除'RemoveItem'導致'cout'問題,但我不認爲就是這樣。如果我有機會仔細觀察,我會更新答案。 –

+0

這是整個項目(lab3.rar):https://skydrive.live.com/redir?resid=8CDFFBA921B002FE!167&authkey=!AGkZQPKd8GFq5vQ – Trts