2013-04-16 240 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