函数返回一个指针

操作系统给程序运行的内存分配了4个区域:
1. 代码区:顾名思义就是存放运行的代码的;
2. 全局数据区:存放全局数据和静态数据以及常量;
3. 栈区: 函数调用时的返回地址,参数压栈,局部变量,返回数据等都存放在栈区;
4. 堆区: 存放程序动态分配的内存(new,malloc等函数分配的)。
栈内存是由系统自己分配和释放的,而堆内存要由程序员自己全全控制的,否则会出现内存泄露.

例子:

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

int * test1()
{
    // 变量a由系统自动分配在栈上,函数调用结束后就会自动由系统销毁
    int a = 10;
    return &a;
}

int * test2()
{
    // malloc函数分配的空间是在堆上,函数调用结束后空间还在
    int * a = (int *)malloc(sizeof(int)*10);
    * a = 10;
    return a;
}

int main()
{
    int *p, *q;
    int k = 5;
    // 重复多次观察变化
    while (k--){
        p = test1();
        //先打印出地址
        printf("p = 0x%x ", p);
        //再打印出变量值
        printf("*p = %d\n", *p);
        Sleep(1000);
    }
    
    // 重复多次观察变化
    k = 5;
    while(k--)
    {
        q = test2();
        //先打印出地址
        printf("q = 0x%x ", q);
        //再打印出变量值
        printf("*q = %d\n", *q);
        Sleep(1000);
    }
    
    return 0;
}

编译后有warning:

运行结果:

分析:

test1()函数中a变量保存在栈上,函数调用结束的时候a的值会释放掉,所以返回后,虽然a的地址还在,但是打印出来时a地址上的值就会变成随机值了。又由于常量10应该是固定的,所以每次打印的地址都是没有变化的。

test2()函数中用malloc函数分配空间,保存在堆上,堆上的内容是需要手动申请和释放的,不会被系统自动清除,所以返回的变量a的地址,里面保存的值还是在那里,所以能打印出10,又由于是每次都重新malloc的,所以地址会有变化,导致每次地址不一样,而且可以看到内存是连续分配的。

test2()中的内存空间没有释放,在每次循环里加上free(q),如下:

while(k--)
{
    q = test2();
    //先打印出地址
    printf("q = 0x%x ", q);
    //再打印出变量值
    printf("*q = %d\n", *q);
    free(q);
    Sleep(1000);
}

这样的话,就能释放掉由malloc开辟的内存,但是结果跟上面有点变化,如图:

可以看到q的地址每次都是这样,可能的解释是,内存按顺序分配,这里每次q申请完内存后又由free释放掉了,所以下次申请的时候还是这一块内存。

总结:

    函数里可以返回指针变量,但是不要返回由系统自动分配的变量的指针(局部变量),只能返回手动分配的内存的指针(有malloc或new生成的)。

(完)

posted @ 2015-07-30 17:01  凤舞十天  阅读(2010)  评论(0编辑  收藏  举报