在下面的类中,承包商应该从主函数中获取一个字符串和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 1。知道为什么吗?
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),但我有兴趣知道为什么上面的代码不起作用并打印 age=1。
Human(//the same parameter as before)
{
//the same memory allocation
*name = iname;
*age = iage;
}
我的第二个问题是为什么析构函数没有在第一个代码中发布?
因为你在构造函数中获取临时变量的地址。对于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
将它们分配到堆上,但随后您需要自己处理它们。
请参阅是否可以在其范围之外访问局部变量的内存?以及有关变量范围、可见性和 RAII 的其他类似问题。