类中C++析构函数的Xcode问题

2fjabf4q  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(107)

我还在学习c++,我现在正在尝试理解构造函数和析构函数。
每当我使用构造函数和析构函数时,我总是得到下面的错误。在我的班上。
test(32992,0x100394380)malloc:***对象0x100707010的错误:未分配释放的指针***在malloc_error_break中设置断点为debug(lldb)
虽然我可以通过删除析构函数来消 debugging 误,但我知道这不是一个好的编程,因为我必须释放内存。
这是我的代码。

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

puruo6ea1#

问题是您正在向avg()传递参数by value。您的示例调用了两个不同的东西s,因此我将尝试通过调用它们s_mains_avg来区分它们。
当通过值传递参数时,Cs_main中的数据复制到s_avg。这是通过copy constructor完成的。您可以指定自己的复制构造函数,但如果您不指定,编译器会为您提供一个复制构造函数。默认的复制构造函数只复制数据;在本例中,student由指针组成,因此默认的复制构造函数复制指针。不复制指针指向的数据。
因为s_avgavg()的本地,所以avg在返回时必须销毁s_avg。因此,avg()在第37行末尾的s_avg上调用student的析构函数。实际上,这意味着avg()在返回时会删除s_main[0]s_main[1]中的指针。
这就产生了main()的问题。因为s_main[0]s_main[1]main()的本地,所以main在返回时必须销毁s_main[0]s_main[1]。因此,main()在第47行末尾调用s_main[0]s_main[1]上的析构函数。和前面一样,析构函数试图删除s_main[0]s_main[1]中的指针--但是它们已经被删除了!这就是你的问题。
有几种方法可以解决这个问题。一是遵守伊戈尔的建议:你不需要指点。然而,我可以想象,也许你需要一个实际场景的指针,而不是这个玩具场景。在这种情况下,另一种处理此问题的方法是通过引用将参数传递给avg()。无论如何,这是C
中大多数时候传递参数的正确方法:你不必担心复制构造函数或者C++专门研究的那些奇怪的东西。准确地说,您应该更改第12行,使其变为

friend float avg(student &);

然后把第28行改成

float avg(student & s){

然后它就能正常工作了
严格地说,你应该使用一个常量引用,除非你计划以某种方式修改数据(这可能发生)。在这种情况下,将第12行更改为

friend float avg(const student &);

第28话

float avg(const student & s){

而且,它会像一种魔力一样起作用
但真的伊戈尔说得对。现代C++的设计是为了帮助你避免指针,正是因为跟踪它们是如此困难,错误的后果是如此危险。引用传递就是一个很好的例子。所以避免使用指针,除非你绝对需要使用它们。

相关问题