C ++破坏指针数组

时间:2014-01-05 18:25:08

标签: c++ arrays pointers destructor dynamic-memory-allocation

所以这是一个关于动态内存分配和对象创建的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();
} 

2 个答案:

答案 0 :(得分:5)

您的学生班级缺少copy assignment Operator,如果没有,{}仅提供shallow copy

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

因此,当stack unwinding期间删除学生对象时,会导致double delete,因为当群组被销毁时阵列已被删除。

答案 1 :(得分:0)

问题是:

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;        
    }