为什么局部变量不超出范围?

史蒂夫

x是局部变量,执行结束后应超出范围fun()
它的地址通过返回的指针和全局指针提供p,该指针指向不再有效的对象。但仍然输出的是5
为什么?

#include <stdio.h> 

int *p = NULL;

int *fun() { 
    int x = 5;  
    p = &x;
    return p; 
} 

// Driver Code 
int main() { 
    printf("%d", *(fun())); 
    return 0; 
} 
拉希德·K。

局部变量在堆栈中分配。当您main()调用fun()时堆栈显示如下:

+---------------+ <---- Stack pointer  
|   local var x |  
+---------------+ <---- Address of 'x'  
| Return addr   |  
|  in main()    |  
+---------------+  
|Local vars of  |  
|   main()      |  
+---------------+  
|     ...       |  
+---------------+  

当您返回main()时,将从堆栈中弹出局部变量,返回的地址和参数。但是不会清除堆栈(顺便说一句,它将消耗过多的CPU!)。因此,只有堆栈指针移动:

+---------------+
|   local var x |
+---------------+ <---- Address of 'x'
| Return addr   |
|  in main()    |
+---------------+ <---- Stack pointer moved with the pops
|Local vars of  |
|   main()      |
+---------------+
|     ...       |
+---------------+

即使未清除堆栈指针上方的所有内容,也将视为无效。所以,这就是为什么你足够幸运得到的值xmain()的函数。

但是,假设您在fun()之后立即调用另一个函数

#include<stdio.h> 
#include<string.h> 

int *p = NULL;

void fun2()
{
  int var = 18;
  int var2 = 43;

  printf("fun2() called, var@%p=%d, var2@%p=%d\n", &var, var, &var2, var2);
}

int *fun() 
{ 
  int x = 5;  
  p= &x;
  return p; 
} 

// Driver Code 
int main(int argc, char *argv[]) 
{ 
  int *px;

  px = fun();
  printf("x@%p=%d\n", px, *px);
  if (argc != 1) {
    fun2();
  }
  printf("x@%p=%d\n", px, *px); 
  return 0; 
} 

当程序不调用fun2()时,它的行为与您相同,但我添加了以下地址的显示x

$ gcc try.c -o try
$ ./try
x@0x7ffd5beb5f04=5

当程序传递任何参数时,我们fun()之后调用fun2()并在调用fun2()之前和之后显示x

$ ./try any_param
x@0x7ffeadacc084=5
fun2() called, var@0x7ffeadacc080=18, var2@0x7ffeadacc084=43
x@0x7ffeadacc084=43

我们可以看到,价值x在调用后更改为43 FUN2() 因为局部变量var2FUN2()已经把在同一地点x的乐趣()正在运行。因此,0x7ffeadacc084堆栈中的相同地址当然是其新值43x实际上是的值var2

这是调用fun2()之后堆栈的样子 _fun()的先前数据已被fun2()的数据覆盖):

+---------------+
|local var var  |
+---------------+ <---- Address of 'var' = 0x7ffeadacc080
|local var var2 |
+---------------+ <---- Address of 'var2' = 0x7ffeadacc084
| Return addr   |
|  in main()    |
+---------------+ <---- Stack pointer moved with the pops
|Local vars of  |
|   main()      |
+---------------+
|     ...       |
+---------------+

PS:堆栈从高地址增长到低地址。因此,var位于比的地址低的地址var2

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

分配对局部变量的引用,如果局部变量超出范围,会超出范围吗?

来自分类Dev

为什么struct变量超出范围

来自分类Dev

为什么此变量超出范围?

来自分类Java

为什么我的变量没有超出范围?

来自分类Dev

为什么rustc说变量“ totalSplitInv”超出范围?

来自分类Dev

装饰器:了解为什么不刷新局部变量

来自分类Dev

C++ 编译器是否会自动为超出范围的局部变量使用 std::move 构造函数?

来自分类Dev

为什么索引超出范围

来自分类Dev

为什么矢量下标超出范围?

来自分类Dev

为什么会超出范围?

来自分类Dev

为什么光标索引超出范围?

来自分类Dev

为什么索引超出范围?

来自分类Dev

为什么索引超出范围?

来自分类Dev

为什么我的for循环超出范围?

来自分类Dev

为什么索引超出范围?(Python)

来自分类Dev

Python为什么不从封闭范围切换到局部变量范围?

来自分类Dev

超出范围的变量

来自分类Dev

使用SecureRandom填充数组:为什么不超出范围?

来自分类Dev

为什么我可以在超出范围的方法中修改List而不返回它?

来自分类Java

为什么增强的for循环的局部变量必须是局部的?

来自分类Dev

将变量分配给数组时,为什么出现数组下标超出范围错误?

来自分类Dev

为什么编译器不总是优化掉局部变量?

来自分类Dev

为什么我在C ++中超出范围,但在Perl中却超出范围?

来自分类Dev

javascript 中语句头的局部变量的范围是什么?

来自分类Dev

为什么解释器调用变量ia局部变量

来自分类Java

为什么在case语句中变量不是局部变量?

来自分类Dev

变量(可能)超出范围

来自分类Dev

setTimeout变量超出范围

来自分类Dev

访问变量超出范围

Related 相关文章

热门标签

归档