函数调用结束时的数组销毁

时间:2012-02-03 06:38:00

标签: c arrays pointers

这是我的代码

#include<stdio.h>
int * fun(int a1,int b)
{
    int a[2];
    a[0]=a1;
    a[1]=b;
    //int c=5;
    printf("%x\n",&a[0]);
    return a;
}

int main()
{
    int *r=fun(3,5);
    printf("%d\n",r[0]);
    printf("%d\n",r[0]);
}

我在Windows 7上运行代码块 每次运行循环时,我都会将输出作为

  

22fee8
  3
  2293700

以下是我不理解的部分:

r需要一个指向内存部分的指针,该指针在调用有趣函数时被解释为一系列框(每个4字节宽度的框 - >整数)

应该发生的是printf of function将打印[0]的地址或地址:

借调

现在的问题是:

每次运行程序时,我都会得到相同的地址吗?

并且在函数调用结束时应该销毁数组a只有函数调用后才能保留指针 那么为什么地球r [0]必须打印3?

5 个答案:

答案 0 :(得分:2)

指向不再存在的东西。您正在返回指向堆栈上某些内容的指针。当fun()结束时,该堆栈将倒带。它之后可以指向任何东西,但没有任何东西覆盖它,因为永远不会调用另一个函数。

答案 1 :(得分:1)

没有任何东西强迫r[0]为3 - 这只是寻求最简单的可接受行为的结果。

基本上,你必须在a结束时销毁fun。所有这些意味着返回的指针(在您的情况下为r完全不可靠。也就是说,即使您的特定计算机上使用特定编译器的r[0] == 3,也无法保证每台计算机都能保留这一点。

要理解为什么它如此一致,请考虑一下:a被摧毁的意义是什么?只有你不能以任何可靠的方式使用它。满足这个简单要求的最简单方法是使堆栈指针移回到调用fun的点。因此,当您使用r[0]时,a的值仍然存在,但它们是垃圾数据 - 您不能指望它们存在。

答案 2 :(得分:1)

这就是:

  • int a[2];分配在堆栈(或类似)上。假设它在地址0x12345678的堆栈处分配。
  • 当阵列被填满时,各种数据被推送到该地址的堆栈上。一切都按预期工作。
  • 返回指向堆栈的地址0x12345678。 (具有讽刺意味的是,地址本身可能会在堆栈中返回。)
  • 堆栈中为a分配的内存不再有效。现在,两个int值仍然位于RAM中的给定地址,包含分配给它们的值。但是堆栈指针不是保留那些单元格,程序中的任何其他东西也不跟踪那些数据。计算机不会通过删除值等来删除数据,它们会通过忘记在内存位置存储任何使用内容来删除单元格。
  • 当函数结束时,这些存储器单元可以自由地用于程序的其余部分。例如,函数返回的值可能会在那里结束。
  • 该函数返回一个指针,指向堆栈上曾经是有效数据的段。指针仍然是0x12345678,但在该地址,现在可能存储任何内容。此外,该地址的内容可能会随着从堆栈中推送/弹出不同的项目而改变。
  • 打印该地址的内容将产生随机结果。或者它可以在每次执行程序时打印相同的垃圾值。事实上,它不能保证打印任何内容:打印无效内存单元格的内容是C中未定义的行为。程序甚至会在您尝试时崩溃。

答案 3 :(得分:0)

函数r的堆栈被释放后,

int * fun(int a1,int b)未定义,在它结束后,它可以是3或42或任何值。它仍然包含您的预期值的事实是因为它没有被用于其他任何东西,因为您的内存的一大块是为您的程序保留的,并且您的程序不会进一步使用堆栈。然后在打印前3后,你得到另一个值,这意味着堆栈被用于其他东西,你可以归咎于printf(),因为它是唯一运行的东西,它做了很多事情让这些数字进入控制台

为什么它总是打印相同的结果?因为你总是做同样的过程,所以没有任何魔力。但是不能保证它不会是3,因为“记忆空间”不是你的,而你只是“窥视”它。

此外,检查编译器的fun()main()的优化级别,如果要优化二进制文件,减少“随机性”,可以内联或替换它们。在你的结果中预期。虽然我不希望它改变太多。

答案 4 :(得分:0)

你可以在这里找到很好的答案:

  1. can-a-local-variables-memory-be-accessed-outside-its-scope
  2. returning-the-address-of-local-or-temporary-variable
  3. return-reference-to-local-variable
  4. Though the examples are for C++, underlying idea is same.