注册 登录
编程论坛 C语言论坛

求助!关于指针的小问题!!

li凡 发布于 2022-07-05 11:54, 1565 次点击
程序代码:

#include <stdio.h>

void f(int **q)   
{
    int i = 6;
    *q = &i;
}

int main()
{
    int * p;
   
    f(&p);
    printf("%d\n",*p);
   
    return 0;
}
/*
在Dev-C++5.11中的输出结果是:
--------------------------------
6

--------------------------------

问题:
    当程序运行完 f(&p); 函数时,f() 函数中的形参 i 在函数终止以后不就被释放掉了吗?
        为什么 *p 最后输出的值还是 6 ?
*/
4 回复
#2
吹水佬2022-07-05 15:08
以下是引用li凡在2022-7-5 11:54:41的发言:
void f(int **q)   
{
    int i = 6;
    *q = &i;
}

这个调用完f()还有什么意义
#3
diycai2022-07-05 16:18
前提你要懂一点汇编知识。

按__cdecl约定调用函数f(&p),伪汇编码如下:(如果不懂调用约定,可以自行百度)
  push &p;  参数入栈,省略了&p的求值过程
  call f;   调用函数f(int **q)

进入函数后:
  push ebp; 保护上一个现场的栈顶(ebp在当前函数内,就是 局部变量与传参的分水岭)
  mov ebp, esp; 设置新的现场栈顶
  sub esp, xx;  给局部变量分配栈空间
  mov [ebp-4], 6;  给局部变量i赋值
  mov *q, &i;  执行 *q = &i;
  mov esp, ebp; 释放局部变量占用的栈(注意,仅仅是esp改变,而释放的区域数据未改变)
  pop ebp; 恢复上一个现场
  ret
函数返回后:
  add esp, 4; 保持栈平衡

  push *p;  printf参数压栈,注意此时栈中上一个函数的i的值并未被覆盖,故此时依旧为6
  push "%d\n"
  call printf
 
#4
rjsp2022-07-05 18:32
问题:
    当程序运行完 f(&p); 函数时,f() 函数中的形参 i 在函数终止以后不就被释放掉了吗?
        为什么 *p 最后输出的值还是 6 ?

因为这是未定义行为,相当于C/C++说“这鬼畜代码我无能为力了,既无法保证一定输出正确的值,也无法保证一定出现错误行为”。

如果还听不懂,那就相当于,你去买房子,然后从13楼一跃而下,摔地上没死,然后气冲冲地去质问开发商“为什么我没死?”
开发商告诉你,你的行为不在他们的施工要求中,既没法保证你必须活着,也没法保证你必须死着。你的行为不在他们的施工要求中,因此属于“未定义行为”。
#5
吹水佬2022-07-05 19:59
以下是引用li凡在2022-7-5 11:54:41的发言:

问题:
    当程序运行完 f(&p); 函数时,f() 函数中的形参 i 在函数终止以后不就被释放掉了吗?
        为什么 *p 最后输出的值还是 6 ?
*/

是“释放”已分配占用的空间出来能被再分配使用,不是“清除”.......
1