类中c ++析构函数的xCode问题

时间:2018-07-07 23:02:59

标签: c++ xcode constructor destructor

我仍在学习c ++,现在我试图理解构造函数和析构函数。

每当我使用构造函数和析构函数时,我只会得到以下错误。 在我班上。

  

test(32992,0x100394380)malloc: *对象0x100707010的错误:   未分配指针   * 在malloc_error_break中设置一个断点以进行调试(lldb)

尽管我可以通过删除Destructor来消除错误,但是我知道这不是一个好的编程,因为我必须释放内存。

这是我的代码。

#include <iostream>
using namespace std;



class student{
private:
    int *age, *mark1,*mark2,*mark3;
    string *name;

public:
    friend float avg(student);
    student(){
        age = new int;
        mark1 = new int;
        mark2 = new int;
        mark3 = new int;
        name = new string;

        cout << "Enter student name: "; cin >> *name;
        cout << "Enter student age: "; cin >> *age;
        cout << "Enter student 3 marks: "; cin >> *mark1 >> *mark2 >> *mark3;
        cout << endl; }

    ~student(){
        delete age;
        delete mark1;
        delete mark2;
        delete mark3;
        delete name; }

    string returnName(){
        return *name; }
};

float avg(student s){
    return (double)(*s.mark1+*s.mark2+*s.mark3)/3;}




int main() {

    student s[2];

    for (int i = 0; i < 2; i++) {
        s[i];
        cout << "Avg of student " << s[i].returnName() << " is " << avg(s[i]) << endl;
    }
}

1 个答案:

答案 0 :(得分:0)

问题是您要按值按值传递参数到avg()。您的示例调用了两种不同的事物s,因此,我将通过分别调用s_mains_avg来区分它们。

当您通过值传递参数时,C ++将s_main中的数据复制到s_avg中。这是通过副本构造器完成的。您可以指定自己的副本构造函数,但如果不指定,则编译器会为您提供一个。默认的复制构造函数只是将数据复制过来。在您的情况下,student由指针组成,因此默认的复制构造函数将复制指针。 它不会复制指针指向的数据。

由于s_avg对于avg()是本地的,因此avg必须在返回时销毁s_avg。因此,avg()在第37行的末尾在student上调用s_avg的析构函数。实际上,这意味着avg()删除s_main[0]中的指针,并且s_main[1]返回时。

这为main()设置了问题。由于s_main[0]s_main[1]main()本地,main必须在返回时销毁s_main[0]s_main[1]。因此,main()在第47行的末尾在students_main[0]上调用s_main[1]的析构函数。像以前一样,该析构函数试图删除两个{{1 }}和s_main[0]-但它们已被删除!因此,您的问题。

有几种方法可以解决此问题。一种是遵守Igor的建议:您实际上并不需要指针。但是,我可以想象,也许您需要针对实际场景的指针,而不是这种玩具场景。在这种情况下,解决此问题的另一种方法是通过引用将参数传递给s_main[1]。无论如何,这实际上是大多数时候在C ++中传递参数的正确方法:您不必担心复制构造函数或C ++专业的任何怪异事物。确切地说,您应该更改第12行,这样读取

avg()

然后更改第28行,使其显示为

friend float avg(student &);

然后它将正常工作。

严格来讲,除非您打算以某种方式修改数据(可能会发生),否则应使用恒定引用。在这种情况下,将第12行更改为

float avg(student & s){

第28行到

friend float avg(const student &);

并且,它将再次像魅力一样工作。

但实际上,伊戈尔是对的。现代C ++旨在帮助您避免使用指针,这恰恰是因为跟踪指针非常困难,并且错误后果非常危险。通过引用传递就是一个很好的例子。因此,除非绝对必须使用指针,否则请避免使用指针。