c++ - 为什么我不能打印工资?

标签 c++

<分区>

我正在编写一个类数据库。

我有一个类对:

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; 对** ar; ...

如果我们添加一个项目,如果容量溢出,数据库就会拉伸(stretch)。 如果我们删除一个项目,就会出现一个空单元格,将来可能会用到。 这样做是为了不使堆碎片过多。

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");

它工作得很好。它打印整个数据库或任何元素。

然后我将 Ivanov 先生移除。 bd.RemoveItem("伊万诺夫");

现在我遇到了这两个问题:

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

我在 Data 类中有一个打印方法。

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

我特地做了第二次cout,因为这是我遇到麻烦的地方。 薪水虽然在范围内清晰可见,但却导致了整个问题。 请看这张照片:

enter image description here

如果我再执行一步,我会收到有关堆损坏的错误消息。 输出窗口显示:HEAP: Free Heap block 296b30 modified at 296b58 after it was freed

你能帮我理解为什么我不能打印这份工资吗?

最佳答案

我在 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
        }

您的 memcpy 是从 ar 复制的,在您递增 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

关于c++ - 为什么我不能打印工资?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16044831/

相关文章:

c++ - 循环复制是否比 memcpy() 效率低?

c++ - 在类定义中允许不必要的分号的目的

c++ - std::uniform_real_distribution 包含范围

C++:将指针的指针传递给函数

c++ - Makefile 编译所有文件,即使更改是在单个 c++ 文件中完成的

c++ - 在 C++ 中调整动态堆栈分配的大小

c++ - 如何从C++中的字符串ID中提取int日、月和年

c++ - 读取位置 0xc3618000 访问冲突

c++ - 从模拟用户下启动的某些系统默认 .lnk 文件的问题

c++ - 在C++中,将类的指针的默认构造函数作为map的值调用