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

Passing an integer into a constructor after dynamic memory allocation

在下面的class中,contractor应该从main函数中取出一个string和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;
     }

输出如下,打印的是 age 而不是 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

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

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

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

因为您在构造函数中获取临时变量的地址。对于 nameage 字段。

Human(string iname, int iage){
    name = new string;
    age = new int;
    name = &iname;
    age = &iage;
}

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

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

只需复制值:

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 的类似问题。