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

标签 c++ xcode constructor destructor

我仍在学习 C++,现在正在努力理解构造函数和析构函数。

每当我使用构造函数和析构函数时,我都会不断收到以下错误。 在我的课上。

test(32992,0x100394380) malloc: * error for object 0x100707010: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug (lldb)

虽然我可以通过删除析构函数来消除错误,但我知道这不是一个好的编程,因为我必须释放内存。

这是我的代码。

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

最佳答案

问题是您将参数按值 传递给avg()。您的示例调用了两个不同的东西 s,因此我将尝试通过调用它们来区分它们 s_mains_avg

当您按值传递参数时,C++ 将 s_main 中的数据复制到 s_avg。这是通过复制构造函数完成的。您可以指定自己的复制构造函数,但如果您不这样做,编译器会为您提供一个。默认的复制构造函数只是将数据复制过来;在您的情况下, 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()s_main[0]s_main[1] 上调用 student 的析构函数第 47 行的结尾。和以前一样,析构函数试图删除 s_main[0]s_main[1] 中的指针——但它们已经被删除了!因此你的问题。

有几种方法可以解决这个问题。一种是遵守 Igor 的建议:您实际上不需要此处的指示。但是,我可以想象,也许您需要针对实际场景而不是这个玩具场景的指示。在这种情况下,另一种处理方法是将参数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){

再一次,它会像魅力一样发挥作用。

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

关于c++ - 类中 c++ 析构函数的 xCode 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51227559/

相关文章:

java - Spring Boot - 找不到合适的构造函数错误

c++ - T::T(T&)有什么用?

c++ - 用 boost 写一个 gz 流

ios - Xcode 8 App 安装失败,发生未知错误

ios - header 未显示在 UICollectionViewController Swift 中

ios - 如何为基于 autotool 的项目启用特定于 Xcode 的构建标志

c++ - 无法理解复制构造函数从何而来

c++ - 创建 SSL 上下文时出错 - Qt

c++ - UB 在未评估的上下文中(例如需要表达式)仍然是 UB 吗?

c++ - Boost ASIO TCP 服务器架构