2.动态内存分配与释放

转载请标明出处:http://blog.csdn.net/u012637501
一、静态内存分配
1.程序运行与内存关系
(1)软件在运行前需要向操作系统申请存储空间,在内存空间足够空闲时,操作系统将分配一段内存空间并将程序从外存拷贝一份存入该内存空间中,并启动该软件运行;
(2)在软件运行期间,该软件所占内存空间不再分配给其他程序;
(3)当该软件运行完毕后,操作系统将回收该内存空间(注意:操作系统并不清空该内存空间遗留下来的数据),以便再次分配给其他软件使用,只是用1标记表示内在是被占用的,用0标记表示是空闲的。
    综上所述,一个软件所分配到的空间中极可能存在着以前其他软件使用过后的残留数据,这些数据被称之为垃圾数据,所以通常情况下我们为一个变量或一个数组,分配好存储空间之前都要对该内存空间初始化。
2.静态内存分配
(1)定义:静态内存,即通过数组在内存中划分一段连续的存储空间,存储空间大小是固定不变的;
(2)缺点:
    a)数组长度必须事先指定,且只能是常整数,不能是变量。如int len=5;int a[len];是错误的;
    b)数组一旦定义,系统就为该数组分配的存储空间就会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放(不是清零,而是没有操作该空间的权限了);
    c)数组的长度不能在函数运行的过程中动态的扩充或缩小;
    d)传统方式定义的数组不能跨函数使用
        A函数定义的数组,在A函数运行期间可以被其他函数使用。但A函数运行完毕之后,A函数中的数组将无法再被其他函数使用。
    #include<stdio.h>
    void g(int * pArr, int len)
    {
            pArr[2] = 88; //parr[2]==a[2] 等价于
    }
    void f(void)
    {
            int a[5] = {1,2,3,4,5}; //数组a 只在f()执行时有效
            g(a,5);
           printf("%d\n", a[2]);
     }
      int main(void)
    {
        f(); // 结果: 88
        //printf("a[0] = %d\n", a[0]); // error
        return 0;
        }
运行结果:a[0]=88
详解:在主函数中调用数组,由于f函数的调用已经结束,主函数无法再调用f函数定义的数组。
二、动态内存分配
1.动态内存分配
(1)动态分配内存与释放

§举例1

/*mallocmemory(内存) allocate(分配)的缩写动态内存空间是怎么造出来的?

*/

#include <stdio.h>

#include <malloc.h>

int main(void)

{

        int i = 5;             //分配了4个字节静态分配

        int * p = (int *)malloc(100);

      *

          1. 要使用malloc函数必须要添加malloc.h头文件

          2. malloc函数只有一个形参,并且形参是整型

          3. 100表示请求系统为本程序分配100个字节

          4. malloc函数只能返回第一个字节的地址,但此时并不能确定该变量的类型,只有将这个地址被强制类型转化成存

                放整型变量的地址,这时才传达出指向整型变量的信息。

          5. 系统总共分配了104个字节的内存空间,p变量本身占4个字节(静态分配),p所指向的内存占100个字节(动态分

                配) 若为int 则可存25个int类型变量(25*4字节),若为char则可存100个变量(100*1字节)。

          6. p本身所占的内存是静态分配的,p所指向的内存是动态分配的

       */

        free(p);

            //free(p)表示把p说指向的内存空间给释放掉,

            //p本身的内存不能释放,只有main函数终止时,由系统自动释放

        *p = 5; 

            //*p代表的就是一个这int变量,*p这个整型变量的内存分配方式和int i =5;不同。

            //*p是内存是动态分配的, int i是静态的。

        printf("*p=%d\n",*p);

        printf("同志们好!\n");

         return 0;

}

运行结果:

§举例2

#include <stdio.h>

#include <malloc.h> 

void f(int * q) //qp的拷贝或副本 q等价于p *q等价于*p *q=200*p=200

{

    //*p = 200; //error f()没有p变量,p是在main()函数定义的

    // q = 200;  //error q是指针变量(地址),200是整数int 

    *q = 200; //OK类型一致

    //  * *q  语法错误 *q整型变量, 只有指针变量前可以加*

    //free(q);//q指向的内存释放掉

}

int main(void)

{

        int * p = (int *)malloc(sizeof(int));//sizeof(int)=4;

        *p = 10; 

        printf("%d\n", *p); //10

        f(p);    //p保存的是地址

        printf("%d\n", *p); //情况1:200

                                    //情况2: f()函数中 free(q)作用后,则输出 -572662307(垃圾值)

        //printf("%d\n", **p);  //语法错误

      return 0;

}

运行结果:200
分析说明:
☆**p语法错误,因为*p是一个常量,指针(*)不能指向一个常量,只能指向地址。
☆int * p = (int *)malloc(sizeof(int)):分配大小为sizeof(int)=4字节的内存空间,并使指针变量p指向该内存空间首地址;

(2)动态构造一个数组
■伪算法:
    >任意指定数组大小,并为其分配相应大小的内存空间;
    >将内存空间的起始地址,赋值给同类型的指针变量pArray;
    >通过pArray,实现数组初始化。
■源码:

/*目的动态一维数组示例

realloc(pArr, 100)

//扩充动态内存空间 (原来50100;原来150100)

//保留原来动态内存中未被截取的内容

*/

#include <stdio.h>

#include <malloc.h> 

int main(void) 

{

    //int a[5]; //系统静态地分配20个字节的空间给数组a

    int len;

    int *pArr; 

    printf("请输入你要存放的元素个数" );

    scanf ("%d", &len);//5

    pArr = (int *)malloc(4*len);//pArr指向这20个字节动态空间的前4个字节

    /*

    动态的构造了一个一维数组该数组的长度len 数组名是pArr, 数组元素类型是int

    类似与int pArr[len]; len可以根据需要变化

    */

    //对一维数组进行操作,如:对动态一维数组进行赋值

    for (int i=0; i<len; ++i)

            scanf("%d", &pArr[i]);   

    printf("动态数组元素为: \n");

    //对一维数组进行输出

     for(i=0; i<len; ++i)

            printf("%d\n", pArr[i]);

    free(pArr);//动态空间被释放

    printf("%d\n", *(pArr+1));  

    //动态空间被释放原来动态数组数元素内容为垃圾值-572662307

    return 0;

}

■运行结果:

(3)使用动态数组的优点:
◆动态数组长度不需要事先给定;
◆内存空间可以手动释放;
◆在程序运行中,动态内存空间大小可以通过realloc函数手动扩充或缩小

2.静态内存(数组)与动态内存(数组)区别
(1)静态内存是有系统自动分配,由系统自动释放;动态内存是由程序员手动分配,手动释放。
(2)静态内存是在栈中分配的;动态内存是在堆中分配的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值