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

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

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

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

时间: 2024-08-01 17:39:59

指针作为形参和返回值的区别的相关文章

函数指针与指针函数返回值的区别

指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针定义: 类型标识符 *函数名(参数表)eg: int *f(x,y);函数指针是指向函数的指针变量,即本质是一个指针变量.int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 函数指针与指针函数返回值的区别,码迷,mamicode.com

C-const和static的区别, 指针作为函数的返回值, 指向函数的指针, 枚举

const和static的区别 const ——只读, 只在声明中使用 1 const int num = 10; 2 int const num = 10; num变量只读, 不能修改 1 const int arr[4] = {10, 20, 30, 40 }; 2 int const arr[4] = {10, 20, 30 ,40 }; 数组的元素的值不能被修改, 只读 1 const int *p1 = &num; 2 int const *p1 = &num; 无法通过p1指针

新手,对函数,函数指针,回调函数, 函数指针作为函数的返回值和block的一些见解

很多初学者,学c语言时,看到函数都觉得难,我也是,一开始觉得函数太难了,后来慢慢就理解了 第一:函数 在c语言中最简单的函数一般有四种: 1, 无返回值, 无参数. 2, 无返回值,有参数. 3, 有返回值,无参数. 4, 有返回值,有参数 1, 无返无参  定义方式:      void 函数名(); 一般不怎么用这种形式的函数,可用来输出,打印 void functionOne() { printf("无返回值,无参数"); // 没有返回值不能写return } int main

传引用作为形参和返回值_节省参数拷贝的时间

基本的传引用概念 #include <bits/stdc++.h> using namespace std; //说出以下两个函数的区别 int& whatf(int &a,int &b) //如果不希望函数执行过程中 某变量被修改 用const限定 { a=3;b=2; return a; } int whath(int a,int b) { a=3;b=2; return a; } int main() { int a,b; whatf(a,b)++; cout&l

execute,executeUpdate,executeQuery返回值的区别

execute,executeUpdate,executeQuery返回值的区别昨天发现了个很有意思的问题,执行插入的sql,sql执行成功,数据成功插入,但是execute返回的结果一直为false,所以差了点资料,看了看源码,找到问题,写个随笔分享一下,希望对大家有帮助 execute返回结果为boolean类型源码: * @return <code>true</code> if the first result is a <code>ResultSet</c

函数指针,函数指针数组,函数返回值为函数指针

函数的名字就是函数的首地址:定义函数指针; int (*p)(int ) p为函数指针变量名字,int 为函数的返回值类型为int型:(int)为函数的形参类型为int型, 注:因为优先级所以要用(*p),否则就会p先和后面的()结合为int*p(int),意思就变为p(int)函数的返回值为int* 注:main2()函数中   int (*p[])(int ,int )  为一维数组,下面写错了, #include<stdio.h> #include<stdlib.h> int

C++ 中的形参与返回值

函数调用时,形参对象和返回对象均采用引用方式进行(临时对象作为中介),当一个对象作为参数(非引用)被函数调用时,该对象会通过复制构造函数获得一个临时对象,该临时对象以引用方式传递给函数,简言之,函数会被做以下处理: void foo(A x); A a foo( a); 处理后:void foo(A& x); A a A x(a): foo(x); 而返回值则根据不同的函数调用方式来进行不同程度的优化,如下面的调用方式,会直接将对象b作为引用传递给函数bar: A bar(); A b = ba

Java引用类型作为形参和返回值

一.什么是引用类型 在Java中引用类型包括三种:类.抽象类.接口. 二.引用类型作为形参使用 1.类作为形参 /** * 类作为形参,实际传递的是该类的对象 */ class Student { public void study() { System.out.println("Good Good Study, Day Day Up"); } } class StudentDemo { public void show(Student s) { s.study(); } } publ

测试函数用Return 返回值和用函数名返回值的区别

'*************************************************************************'**模 块 名:工程1 - Form1'**说    明:蓝凤凰设计商城 浴火凤凰-郭卫 | 蓝凤凰-魔灵 | 郭卫-icecept'**创 建 人:浴火凤凰-郭卫'**日    期:2015年10月19日  21:53:17'**修 改 人:浴火凤凰-郭卫'**日    期:'**描    述:QQ:493405998 | 微信\旺旺:icece