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



在下面的类中,承包商应该从主函数中获取一个字符串和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;
      }

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

因为你在构造函数中获取临时变量的地址。对于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 将它们分配到堆上,但随后您需要自己处理它们。


请参阅是否可以在其范围之外访问局部变量的内存?以及有关变量范围、可见性和 RAII 的其他类似问题。

最新更新