我仍在学习 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_main
和 s_avg
。
当您按值传递参数时,C++ 将 s_main
中的数据复制到 s_avg
。这是通过复制构造函数完成的。您可以指定自己的复制构造函数,但如果您不这样做,编译器会为您提供一个。默认的复制构造函数只是将数据复制过来;在您的情况下, student
由指针组成,因此默认的复制构造函数复制指针。 它不会复制指针指向的数据。
因为 s_avg
是 avg()
的局部变量,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/