销毁函数中的局部变量是什么意思?

问题描述 投票:2回答:7

销毁局部变量是什么意思。

void f()
{      
   int x=10;     
}

当该函数调用时,函数结束时,局部变量就会被销毁 x 会是什么?

而对于。

void f2()
{
  int a=100;
  int* b=&a;
}

结束 f2() 该局部变量是什么 b'的价值?将 b 指针是一个悬空指针(有地址但没有任何值)?

c++ function c++11 pointers scope
7个回答
9
投票

当该函数调用时,函数结束时那个局部变量x会是什么?

不存在。 蒸发了。 蒸发了。 消失了。

x 这里是一个具有自动寿命的变量。 "自动 "指的是,当 x 出了范围,就会被销毁。 (不完全是 删除,因为该词意味着调用 delete)

所有的自动变量也是如此,不管它们是积分、字符串、浮点数,甚至是指针。

void f2()
{
  int a=100;
  int* b=&a;
}

在这里... ab 是自动变量。 它们都会在它们的作用域结束时被销毁--即在 f2(). 然而,所有被销毁的都是变量本身。 如果一个自动变量是一个指针(例如,一个 原始 指针),那么 指针指向的东西 被摧毁。 考虑到。

void f3()
{
  char* p = new char [256];
}

p 这里仍然是一个自动变量,类型为指针到查尔。 这个东西 p 指向不是自动的 -- 那是动态分配的(我们使用了 new).

如上所述。p 会被销毁,但它所指向的内存不会。 这就是内存泄漏。 为了解决这个问题,你必须 delete 它。

void f3()
{
  char* p = new char [256];
  delete [] p;
}

现在,记忆指的是... p 已被正确销毁,而指针本身 (p)将在其范围结束时被销毁,因为它是一个自动的。

的寿命。p 和什么 p 指的是没有任何联系的。 就因为你 delete 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"
}

After the delete的值,我们打印出 p 到屏幕上。 如果你运行这个程序,你会看到 p 与删除前相比并没有变化。 p 本身不受 delete [] p;. 但在 f3()的收尾支架 },它将从作用域中掉出来,并在那里被销毁。


0
投票
  1. 本地变量是在堆上自动为你分配的,当你退出函数的作用域时,它会自动释放(因此被销毁)。
  2. b 不会是一个悬空的指针,因为你没有在堆上分配任何内存(使用了 mallocnew它只是一个指向本地变量的地址的指针。a (当你退出函数的作用域时就会被销毁)

0
投票

一旦该函数的堆栈框架被弹出......你就不能再引用那些局部变量。


0
投票

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!
}

0
投票

变量 x, ab 都是局部变量,所以它们在函数返回后就不存在了。如果你试图询问其中任何一个变量的值是什么,调试器可能会说 "找不到 x 在这种情况下"。

更详细地说,这些变量的内存是从堆栈中分配的,并在函数返回时返回到堆栈中。调用 f() 本质上是将值10放在堆栈的顶部;如果你再创建另一个 int 在堆栈上未初始化,它可能会从10开始(你不应该依赖这种行为,因为它没有保证,但它给了你一个关于堆栈在许多系统上如何工作的基本概念)。


0
投票

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

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

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


0
投票

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

但如果考虑到以下情况。

int *global;

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

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

© www.soinside.com 2019 - 2024. All rights reserved.