关于函数形参的理解

问题背景

关于函数调用时的形参问题,很多人都会遇到坑,特别是一些指针的传参,可能因为理解上的疑惑,从而出现一些内存泄露问题!

知识点前提

  • 栈的理解
  • 函数调用过程

说明

先直接上一段代码:

#include <stdio.h>

void func(char *p, int *val)
{
    int a = 100;
    p = "hello world";
    val = &a;

    printf("val[%p] = %d \n", val, *val);
    printf("p %p,%s\n", p, p);
}

int main()
{
    char *p = NULL;
    int *val = NULL;
    printf("p=%p \n", &p);
    func(p, val);
    printf("p:%p, %s \n",p, p);

    return 0;
}

问题

  1. 上面在调用func()函数后,发生了什么?
  2. 最后打印p的时候,p有没有值?
函数调用过程
  1. 简单来说,函数调用func()函数后,会进行保存上下文、形参压栈操作,即将p,val进行数据的拷贝到一个栈空间中,也就是在函数调用后,p的形参地址(压栈时的地址)和原来的p并不是同一个地址,但是其值一样。
  2. 也就说函数func()压栈之后,func()函数的2个指针指向内容都是NULL。后来将val指向函数内存的栈数据a,也就是100,所以后面*val就是100。但是需要注意,这个val只是一个拷贝,也就是说这个栈空间的数据指向了a这个地址,但是main()函数的值并没有发生改变!同样可以对p进行分析。
  3. func()函数结束后,这部分栈空间被回收,也就是这个val他是一个已被回收的空间,是一个垃圾值!如果你继续使用这个地址值,那可能会造成内存泄露!
  4. 执行完func(),p依旧是还是NULL;
提问
  1. 如果我想让val发生改变,我怎么做?

将func(p,val),改成func(p,&val),理解如下:

  1. 调用后,是对&val的拷贝,其值就是val的地址,如果操作*val=100,就代表这将这个val指向的值改成100,这里再理解一下,就是说这个拷贝的值是val指向的地址的地址,这个val指向地址就是外部val的地址,所以即使被调用销毁了,其外部val的值已经改变了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值