C++ 破坏函数中的局部变量有什么意义

C++ 破坏函数中的局部变量有什么意义,c++,function,c++11,pointers,scope,C++,Function,C++11,Pointers,Scope,销毁局部变量的含义是什么: void f() { int x=10; } 当该函数调用时,该局部变量x将是什么 以及: void f2() { int a=100; int* b=&a; } f2()的结尾局部变量b的值是多少?b指针是否为悬空指针(将有地址,但其中没有任何值) 当该函数调用时,局部变量x将调用的函数结束 是什么 不存在。蒸发的。水蒸气走了 x这是一个具有自动生存期的变量。“自动”是指当x超出范围时,它将被销毁。(不完全删除,因为该

销毁局部变量的含义是什么:

void f()
{      
   int x=10;     
}
当该函数调用时,该局部变量
x
将是什么

以及:

void f2()
{
  int a=100;
  int* b=&a;
}
f2()的结尾局部变量
b
的值是多少?
b
指针是否为悬空指针(将有地址,但其中没有任何值)

当该函数调用时,局部变量x将调用的函数结束 是什么

不存在。蒸发的。水蒸气走了

x
这是一个具有自动生存期的变量。“自动”是指当
x
超出范围时,它将被销毁。(不完全删除,因为该术语意味着调用
delete

所有自动变量也是如此,它们可以是积分、字符串、浮点,甚至是指针:

void f2()
{
  int a=100;
  int* b=&a;
}
这里
a
b
都是自动变量。它们都将在其作用域的末尾销毁--
f2()
的末尾。然而,所有将被破坏的是变量本身。如果一个自动变量是一个指针(例如,一个原始指针),那么指针指向的东西将被销毁。考虑:

void f3()
{
  char* p = new char [256];
}
p
这里仍然是一个自动变量,类型为指向char的指针。
p
指向的东西不是自动的——是动态分配的(我们使用了
new

如上所述,
p
将被销毁,但它指向的内存不会被销毁。这是内存泄漏。要解决此问题,您必须删除它:

void f3()
{
  char* p = new char [256];
  delete [] p;
}
现在,由
p
指向的内存已被正确销毁,指针本身(
p
)将在其作用域结束时销毁,因为它是自动的

p
的生存期和
p
指向的内容没有以任何方式连接。仅仅因为你
删除
p
并不意味着
p
本身现在也被销毁了<代码>p
仍然是一个自动变量

例如:

void f3()
{
  char* p = new char [256];
  cout << (void*) p << "\n"
  delete [] p;
  // p still exists, it just points to to nothing useable
  cout << (void*) p << "\n"
}
void f3()
{
char*p=新字符[256];

cout变量
x
a
b
都是局部变量,因此在函数返回后它们就不存在了。如果您试图询问其中任何一个的值,调试器可能会说“在这个上下文中找不到
x

更详细地说,这些变量的内存是从堆栈分配的,并在函数返回时返回到堆栈。调用
f()
基本上将值10放置在堆栈顶部的正上方;如果随后在未初始化的堆栈上创建另一个
int
,则它可能以值10开始(您不应该依赖此行为,因为它不能保证,但它让您基本了解堆栈在许多系统上的工作方式)

  • 局部变量在堆栈上自动分配给您,并在您退出函数范围时自动释放(因此被销毁)
  • b
    不会是一个悬空指针,因为您没有在堆上分配任何内存(使用
    malloc
    new
    ,它只是指向局部变量
    a
    地址的指针(退出函数作用域时会被销毁)

  • 指针本身也将超出范围。指针
    f2
    在函数结束时被销毁,在这种情况下不会造成内存泄漏,因为它指向的对象位于堆栈上,并且不是使用
    new
    创建的

    但如果你考虑以下情况:

    int *global;
    
    void foo()
    {
    int a = 10;
    global = &a;
    }
    

    然后,指针
    global
    foo
    完成运行后存在,但指向一个已销毁的范围外变量,该变量的值未定义。

    一旦弹出该函数的堆栈帧…当
    f()时,您不能引用这些局部变量
    退出,
    x
    将不再存在。从技术上讲,用于它的内存当然会保留下来,但编译器/系统可以随意使用该内存空间。它最终会将其重新用于完全不同的用途

    如果获取
    x
    的地址并将其从函数中传递出去,则取消引用该指针是最糟糕的未定义行为。例如:

    int* f() {
        int a;
        return &a;
    }
    
    int main() {
        int* pointer = f();
        //int b = *pointer;    //Undefined behaviour, the compiler could choose to format your harddrive now!
    }
    

    你没有破坏任何东西,你的变量超出了范围

    因为它不是堆分配的,所以在内存管理方面不会有任何问题


    如果你真的想学习这些机制的机制,你可以下载ollydbg(假设是windows),并在执行此函数之前、期间和之后进入,以了解现代编程语言和编译器如何处理局部变量。

    您没有任何
    删除
    ,并且由于您没有
    新建
    ,因此没有内存泄漏。“在堆栈框架上”你不知道,我的意思是C++标准没有提到栈、堆或任何类似的东西。一些系统,比如嵌入式或异类硬件,甚至可能没有堆栈指针。因为我们这里不讨论一个特定的平台,你不能说它在堆栈框架上,因为C++中没有堆栈框架。好的,大多数C++编译器都使用栈帧的正确方法。如果你能把我指给任何栈,那么我就不能把你指向任何无栈的实现,因为我不熟悉任何一个。我所熟悉的是描述LAGUAGE本身的标准。是的,大多数HA上的编译器。RDWRADE使用堆栈框架(实际上是使用堆栈帧的CPU),但是C++本身不需要硬件使用堆栈帧,或者甚至对硬件做任何特定的允许。“用于它的内存仍然是”你不知道T。