在下面的课程中,承包商应该从主要功能中获取一个字符串和int(" Jan",24)。但是当传递整数时,似乎有一些错误,因为另一个随机整数(如1)会被打印为年龄。
#include <iostream>
#include <string>
using namespace std;
class Human{
private:
string *name;
int *age;
public:
Human(string iname, int iage){
name = new string;
age = new int;
name = &iname;
age = &iage;
}
void display(){
cout << "Hi I am "<<*name<<" and i am "<<*age<<" years old"<<endl;}
~Human(){
delete name;
delete age;
cout << "all memories are released"<<endl;
}
};
int main()
{
Human *Jan = new Human("Jan",24);
Jan->display();
delete Jan;
return 0;
}
输出如下,打印年龄而不是24岁。任何想法为什么?
Hi I am Jan and I am 1 years old
untitled(5417,0x7fff8ed19340) malloc: *** error for object
0x7ffeed4c19b8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
我知道如果我将我的构造函数更改为以下它将按预期工作(年龄= 24),但我很想知道为什么上面的代码不起作用并且打印年龄= 1.
Human(//the same parameter as before)
{
//the same memory allocation
*name = iname;
*age = iage;
}
我的第二个问题是为什么析构函数不会在第一个代码中被释放?
答案 0 :(得分:5)
因为您在构造函数中获取临时变量的地址。适用于name
和age
字段。
Human(string iname, int iage){
name = new string;
age = new int;
name = &iname;
age = &iage;
}
当它被调用为Human("Jan", 24)
时。
该指令完成后,Jan
和24
的地址不再有效 - 意味着他们可能指向任何。
只需复制值:
class Human {
private:
string name;
int age;
...
另一种解决方案是,如果您可以延长(当前临时)变量的寿命:
{
string name = "Jan";
int age = 24;
{
Human *Jan = new Human(name, age);
Jan->display();
delete Jan;
}
// &name and &age still valid, until closing bracket
}
// &name and &age no longer valid
或者,您可以通过new
在堆上分配它们,但是您需要自己处理它们。
请参阅Can a local variable's memory be accessed outside its scope?以及有关变量范围,可见性和RAII的其他类似问题。