在动态内存分配后将整数传递给构造函数

Sep*_*eha 1 c++ destructor pass-by-reference dynamic-memory-allocation

在下面的类中,承包商应该从main函数中获取一个字符串和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;
     }
Run Code Online (Sandbox Code Playgroud)

输出如下,打印年龄而不是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
Run Code Online (Sandbox Code Playgroud)

我知道如果我将我的构造函数更改为以下它将按预期工作(年龄= 24),但我很想知道为什么上面的代码不起作用并打印age = 1.

    Human(//the same parameter as before)
    {
      //the same memory allocation
      *name = iname;
      *age = iage;
      }
Run Code Online (Sandbox Code Playgroud)

我的第二个问题是为什么析构函数不会在第一个代码中被释放?

Ada*_*ski 5

因为您在构造函数中获取临时变量的地址.对于这两个nameage领域.

Human(string iname, int iage){
    name = new string;
    age = new int;
    name = &iname;
    age = &iage;
}
Run Code Online (Sandbox Code Playgroud)

当它被调用为Human("Jan", 24).

在该指令完成后,地址Jan24不再有效 - 意味着它们可以指向任何东西.

只需复制值:

class Human {
private:
    string name;
    int age;
...
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是,如果您可以延长(当前临时)变量的寿命:

{
  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
Run Code Online (Sandbox Code Playgroud)

或者,你可以在堆上分配它们new,但是你需要自己处理它们.


请参阅可以在其范围之外访问局部变量的内存吗?以及关于变量范围,可见性和RAII的其他类似问题.