C++内存管理-堆栈和堆

C++ Memory Management - The stack and the heap

本文关键字:堆栈 内存 管理 C++      更新时间:2023-10-16

我是C++的初学者,有一个关于变量的问题。

例如,如果我有这种方法:

int wow() 
{
    int x = 99;
    return 0;
}

当这个方法退出(返回0)时,它会破坏变量x吗?

这个变量存储在堆栈中还是堆中?

例如,我知道你可以做int*x=new int(99),然后它就会在堆中。

但如果没有*,它在堆栈中吗?

在上面的方法中,当它退出时,x被破坏了吗?

当这个方法退出(返回0)时,它会破坏变量x吗?

是的。x具有自动存储持续时间,当它超出范围时(在本例中,当函数返回时)会被销毁。

这个变量存储在堆栈中还是堆中?

在堆栈上。

例如,我知道你可以做int *x = new int(99),然后它就会被堆起来。

的确;new创建的对象具有动态存储持续时间,并且在堆上。注意,还有第二个对象x,一个指向堆上对象的指针。x本身是堆栈上的一个自动对象。(从理论上讲,C++将动态内存的来源称为"自由存储",而不是"堆")。

但如果没有*,它在堆栈内吗?

如果没有*,它就无法编译。new在从堆中获取的内存中创建一个对象,并给出它的地址。*表示x是一个指针,因此可以保存该地址。如果没有它,它将是int,无法保存地址。

在上面的方法中,当它退出时,x被破坏了吗?

指针x为;但它指向的对象不是。动态对象(使用new创建)持续到使用delete显式销毁为止。如果这种情况从未发生过,那么就会出现内存泄漏-内存已分配但从未释放。

除非你真的需要,否则要避免动态分配;当你这样做的时候,总是使用智能指针、容器等来安全地管理它,避免使用new和篡改原始指针。

在您的情况下,x通常会保存在处理器寄存器中,并且根本不会占用任何内存(使用优化编译器)。如果编译器需要释放寄存器,它会将变量溢出到堆栈。

编译器从不自动将对象放在堆上。

int x = 99;在堆栈上声明一个变量。

当函数返回时,它被"破坏"了,因为内存被释放供其他函数使用,但通常没有显式擦除。

更明确地说,destroy意味着我们下次查看该内存位置时无法可靠地期望相同的值。但是,因为没有显式覆盖,所以下次我们查看内存位置时,它可能会出现在那里。

声明中使用*符号时的说明。

int *ptr声明了一个指向整数的指针,但这个指针可以指向堆栈或堆,这取决于您决定将其指向哪里

堆:

int* ptr = new int(100);
int* ptr2 = ptr; // Now you have two pointers to the same location in the heap

堆叠

int stackMe = 100;
int* ptrToStack = &stackMe; // Point ptrToStack at an `int` on the stack.

在任何一种情况下,都可以通过指针修改值。

*ptr = 5; // set the `int` that ptr points to, to 5.