码迷,mamicode.com
首页 > 其他好文 > 详细

指针作为形参和返回值的区别

时间:2019-08-14 00:04:40      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:argv   区别   fun   png   data   ima   需要   print   alt   

关于指作为针形参与返回值的常见问题

1、返回栈中局部变量的地址

#include <stdio.h>

int *fun(){
    int a = 10; // a为当前方法栈中的局部变量,结束即释放
    return &a;  // 所以传递出去的会是一个无效(非法)地址
}

int main(int argc, char const *argv[])
{
    int *a = NULL;
    a = fun();
    *a = 100;   // error,操作非法内存
    printf("a = %d\n", *a);
    return 0;
}

2、返回data区的地址

代码同上,不同之处在于a加个static,变为静态局部变量,等同于全局变量

#include <stdio.h>

int *fun(){
    static int a = 10; // 静态局部变量,不会随着方法栈自动释放
    return &a; // 返回的是有效地址
}

int main(int argc, char const *argv[])
{
    int *a = NULL;
    a = fun();
    *a = 100;   // ok
    printf("a = %d\n", *a);
    return 0;
}

3、指针作为形参传递(一)

#include <stdio.h>
#include <stdlib.h>

void fun(int *tmp){
    tmp = (int *)malloc(sizeof(int));   // 形参局部指针变量只在当前方法栈中有效
    *tmp = 100;  // 当前栈中tmp动态分配的内存未释放,造成内存泄漏
}

int main(int argc, char const *argv[])
{
    int *p = NULL;
    fun(p); // p是空指针,没有指向,把p的值传给tmp
    printf("*p = %d\n", *p);    // error 操作空指针所指向的内存
    return 0;
}    

此时fun()函数和main()函数同级,tmp作为fun中的形参局部变量,对其操作不会影响main中的实参p;

并且给tmp在堆中动态分配内存,但是tmp随着fun方法栈的释放而消失,堆中的内存没有释放,造成内存泄漏。

技术图片

4、指针作为形参传递(二)

#include <stdio.h>
#include <stdlib.h>

void fun(int *tmp){
    *tmp = 100;
}

int main(int argc, char const *argv[])
{
    int *p = NULL;
    p = (int *)malloc(sizeof(int));
    fun(p); // 值传递
    printf("*p = %d\n", *p);    // 100
    return 0;
}

此时在fun()函数中操作的不是指针变量tmp,而是tmp所指向的堆内存(没有改形参本身),也就是fun()方法栈中和main()方法栈中的两个变量tmp和p指向了同一块堆内存,fun()方法栈的释放并不会影响操作结果

技术图片

5、指针作为返回值

#include <stdio.h>
#include <stdlib.h>

int * fun(){
    int *tmp = NULL;
    tmp = (int *)malloc(sizeof(int));   // 在堆中分配内存
    *tmp = 100;                         // 堆内存赋值
    return tmp;                         // 返回堆区地址,函数调用完毕不释放
}

int main(int argc, char const *argv[])
{
    int *p = NULL;
    p = fun(p);
    printf("*p = %d\n", *p);    // 100

    // free :堆区空间需要手动释放
    if (p != NULL) {
        free(p);
        p = NULL;
    }
    
    return 0;
}

和第3的区别在于不是通过形参给变量赋值,而是直接返回了指针变量,注意:这里返回的不是栈区的局部变量地址(第1),而是堆区的地址,堆区变量是不会自动释放的,所以返回是合法的。

指针指向同图4

指针作为形参和返回值的区别

标签:argv   区别   fun   png   data   ima   需要   print   alt   

原文地址:https://www.cnblogs.com/jixiaohua/p/11349112.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!