2

破坏局部变量是什么意思:

void f()
{      
   int x=10;     
}

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

对于:

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

f2()那个局部变量的值到底是什么b?指针会b是一个悬空指针(有地址但没有任何值)吗?

4

7 回答 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)将在其范围结束时被销毁,因为它是自动的。

生命周期pp指向的内容没有任何联系。仅仅因为你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"
}

之后delete,我们将 的值打印p到屏幕上。如果你运行它,你会看到p删除它之前的值并没有改变。 p本身不受delete [] p;. 但是在f3()'s 的右大括号处},它将超出范围并被销毁。

于 2013-11-08T19:23:11.493 回答
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!
}
于 2013-11-08T19:28:00.953 回答
0

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

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

于 2013-11-08T19:24:45.513 回答
0
  1. 局部变量会在堆栈上自动为您分配,并在您退出函数范围时自动释放(因此被销毁)。
  2. b不会是悬空指针,因为您没有在堆上分配任何内存(使用mallocor new,它只是指向局部变量地址的指针a(退出函数范围时被销毁)
于 2013-11-08T19:25:31.537 回答
0

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

但是,如果您考虑以下情况:

int *global;

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

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

于 2013-11-08T19:25:37.627 回答
0

一旦该函数的堆栈帧被弹出......你不能引用那些局部变量

于 2013-11-08T19:26:05.057 回答
0

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

由于它没有分配堆,因此您不会在内存管理方面遇到任何问题。

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

于 2013-11-08T19:34:06.140 回答