C++销毁指针数组

C++ destructing array of pointers

本文关键字:数组 指针 C++      更新时间:2023-10-16

所以这里有一个关于动态内存分配和对象创建C++练习。基本上 - 一个自定义类学生和一个自定义类组,其中保留了一系列指向学生的指针。Group的析构函数显然存在问题,但我花了几个小时阅读手册和冲浪论坛,但仍然无法理解我做错了什么。

欢迎任何意见。
UPD:问题是 - 退出时出错。"调试断言失败... _BLOCK_TYPE_IS_VALID..."

class Student{
    char *firstName;
    char *lastName;
public:
    Student(): firstName(NULL), lastName(NULL){}
    Student(const char *fname, const char *lname){
        firstName = new char[32];
        lastName = new char[32];
        strcpy_s(firstName, 32, fname);
        strcpy_s(lastName, 32, lname);
    }
    void Show(){
        cout << firstName << " " << lastName << endl;
    }
    ~Student(){
        if(lastName != NULL)
            delete[] lastName;
        if(firstName != NULL)
            delete[] firstName;
    }
};
class Group{
    Student *students;
    int studentCounter;
public:
    Group(){
        students = NULL;
    }
    Group(const int size){
        students = new Student[size];
        studentCounter = 0;
    }
    void Push(Student *student){
        students[studentCounter] = *student;
        studentCounter++;
    }
    void ShowAll(){
        for(int i = 0; i < studentCounter; i++){
            students[i].Show();
        }
    }
    ~Group(){
        if(students != NULL)
            delete[] students;                //problem here?
    }
};
void main(){
    Student jane("Jane", "Doe");
    Student john("John", "Smith");
    Group group(2);
    group.Push(&jane);
    group.Push(&john);
    group.ShowAll();
    _getch();
} 

您的学生班级缺少复制赋值运算符,如果没有该运算符,则提供的默认赋值运算符仅执行浅层副本。

当您创建学生对象并推入 Group 时,在没有赋值运算符的情况下,学生对象和其数组中持有的一个 Group 对 firstName 和 lastName 数组的引用相同,这应该创建这些数据结构的克隆。

因此,当在堆栈展开期间删除学生对象时,它会导致双重删除,因为在销毁组时数组已经被删除。

问题是:

students[studentCounter] = *student;

您需要编写一个赋值运算符(operator=),以便复制内部缓冲区,而不仅仅是复制地址。

发生的情况是 firstNamelastName 变量被删除两次。

class Student{
//...
public:
    Student& operator=(const Student& rhs) {
        delete firstName;
        delete LastName;
        firstName = new char[32];
        lastName = new char[32];
        strcpy_s(firstName, 32, rhs.firstName);
        strcpy_s(lastName, 32, rhs.lastName);
        return *this;        
    }