在函数中破坏局部变量的意义是什么

时间:2013-11-08 19:19:46

标签: c++ c++11

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

void f()
{      
   int x=10;     
}

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

并且:

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

结束f2()那个局部变量int * b'的值是多少? b指针将是悬空指针(将有地址,但没有任何值)?

7 个答案:

答案 0 :(得分:9)

  

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

不存在。 Evaportated。汽。消失了。

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

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

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

此处ab都是自动变量。它们都将在其范围的末尾被销毁 - f2()的结尾。然而,所有将被破坏的都是变量本身。如果自动变量是指针(例如,原始指针),则指针指向的事物将被销毁。考虑:

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

p这里仍然是一个自动变量,类型指针指向char。 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"
}

delete之后,我们会将p的值打印到屏幕上。如果你运行它,你会发现p的值在删除它之前没有变化。 p本身不受delete [] p;的影响。但是在f3()的右括号},它将超出范围并且会被破坏。

答案 1 :(得分:0)

变量xab都是局部变量,因此在函数返回后它们不再存在。如果你试图询问它们的价值是什么,调试器可能会说“在这种情况下找不到x”。

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

答案 2 :(得分:0)

  1. 本地变量在堆栈上自动为您分配,并在您退出函数范围时自动释放(因此被破坏)。
  2. b不会是一个悬空指针,因为你没有在堆上分配任何内存(使用mallocnew,它只是一个指向本地地址的指针变量a(在退出函数范围时销毁)

答案 3 :(得分:0)

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

但是如果你考虑以下情况:

int *global;

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

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

答案 4 :(得分:0)

弹出该函数的堆栈框架后...您无法引用这些局部变量

答案 5 :(得分: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!
}

答案 6 :(得分:0)

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

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

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