关于C++内存管理的基本问题

And*_*eev 1 c++ memory heap stack new-operator

// main.cpp

class Cat()
{
public:
     Cat()
     {
          a = 0;
          (*b) = 0;
     }

     int a;
     int* b;
};

int main(int argc, char* argv[])
{
     Cat cat1;
     Cat* cat2 = new Cat();
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

Usially我不关心的记忆,但我想了解清楚,在什么内存做cat1的和cat2ab存在吗?在堆栈中还是在堆中?

@BoPerson:你说对了,我应该用过b = new int(0).但是对我来说更有意思,在堆中创建a对象时哪里可变Cata在堆里呢?并且指针b也在堆中,它指向堆中的内存,对吧?

Til*_*gel 7

让我注释并就地回答.

class Cat()
{
public:
     Cat()
     {
          a = 0; // ok: sets the variable a, wherever it lives
          (*b) = 0; // not ok: stores an integer 0 to wherever b points
                    // since b was never initialized to anything, it can write
                    // anywhere you can imagine. If you are lucky, your compiler
                    // implicitly initializes the pointer to zero such that you
                    // at least get a deterministic segmentation violation.
     }

     int a; // an integer variable living wherever Cat gets constructed
     int* b; // a pointer variable living wherever Cat gets constructed pointing 
             // to wherever it gets set to (b = something) could be heap, stack, 
             // mapped memory, out-of-control (like here)
};

int main(int argc, char* argv[])
{
     Cat cat1; // allocates cat1 on the stack, all attributes (a and b) live 
               // there. Where cat1.b points to is unrestricted.
     Cat* cat2 = new Cat(); // allocates an object of class Cat on heap, 
               // allocates a pointer variable cat2 on the stack and stores the 
               // pointer to said heap-allocated Cat in it
               // again, where cat2.b points to is unrestricted.
     return 0; // maybe never reached due to segfault ;-)
}

当您在标题中引用内存管理时:堆栈变量在超出范围时会自动被破坏.即离开main()时将占用的空间cat1cat2(一个Cat,一个指针)将被恢复.此外,对于cat1,将调用析构函数.在您的情况下,没有明确的析构函数,但如果Cat具有析构函数的属性,则会自动生成自动析构函数.

对于指针,当指针被破坏时,指向的对象不会自动被破坏.如果你想要的话,你应该看看像std :: auto_ptr <>(或Qt中的QScopedPoiner)这样的智能指针,它会给你一个类似指针的对象,它确实会破坏指向对象(通过调用它上面的delete)当auto_ptr被破坏时

不使用智能指针时,需要注意使用delete运算符手动破坏指向对象.注意在当前范围的每个返回路径上执行此操作(多次返回,抛出异常,例如).