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

时间:2017-10-31 23:41:21

标签: c++ pass-by-reference destructor dynamic-memory-allocation

在下面的课程中,承包商应该从主要功能中获取一个字符串和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;
      }

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

1 个答案:

答案 0 :(得分:5)

因为您在构造函数中获取临时变量的地址。适用于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的其他类似问题。