C语言学习(6)---内存分配

一、传统数组的缺点:

1、数组的长度必须事先定制,且只能是常整数,不能是变量

  1. int len = 5; int a[len];  //error  

2、传统形式定义的数组,该程序的内存程序员无法手动释放

  1. # include <stdio.h>  
  2.   
  3. void f(void){  
  4.     int a[5] = {1, 2, 3, 4, 5};  
  5.     //这二十个字节的存储空间程序员无法手动编程释放它  
  6.     //只能在本函数运行完毕时由系统自动释放  
  7. }  
  8.   
  9. int main(void){  
  10.     return 0;  
  11. }  

3、数组的长度不能在函数运行的过程中动态的扩充或缩小

4、A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行完毕后,A函数中的数组将无法被其他函数使用,静态数组不能跨函数使用。

  1. # include <stdio.h>  
  2. void g(int *pArr, int len){  
  3.     pArr[2] = 88;  
  4. }  
  5. void f(void){  
  6.     int a[5] = {1, 2, 3, 4, 5};  //f运行期间g();函数可以使用  
  7.     g(a, 5);                    //当f运行完毕数组a空间被释放  
  8.     printf("%d\n", a[2]);  
  9. }  
  10.   
  11. int main(void){  
  12.     return 0;  
  13. }  

二、动态分配

为什么要动态分配?动态分配数组可以很好的解决上面四个问题。

举例:动态数组

  1. /* 
  2.     2012年2月5日15:00:25 
  3.     malloc 是 memory(内存) allocate(分配)的缩写 
  4. */  
  5. # include <stdio.h.  
  6. # include <malloc.h>  //头文件  
  7.   
  8. int main(void){  
  9.     int i = 5; //静态分配了四个字节  
  10.     int * p = (int *)malloc(4);  //把返回的地址强制转换为整形变量的地址  
  11.     /* 
  12.         1.要使用malloc函数,必须添加malloc.h这个头文件 
  13.         2.malloc函数只有一个形参,并且是整型 
  14.         3.4表示请求系统为本程序分配4个字节 
  15.         4.malloc函数只能返回第一个字节的地址 
  16.         5.上面一行代码分配了8个字节,p变量占4个字节,p所指向的内存也占4个字节 
  17.         6.p本身所占的内存是静态分配的,p所指向的内存是动态分配的 
  18.     */  
  19.     *p = 5; //*p代表整形变量,只不过*p这个整形变量的内存分配方式和i分配不同  
  20.     free(p);  //表示把p所指向的内存给释放掉  
  21.     printf("同志们好!\n");  
  22.       
  23.     return 0;  
  24. }  
  1. # include <stdio.h>  
  2. # include <malloc.h>  
  3.   
  4. void f(int * q){  
  5.     *q = 200;  
  6.     free(q);  //把q指向的内存释放掉 和 free(p)等价  
  7. }  
  8. int main(void){  
  9.     int * p = (int *)malloc(sizeof(int));  
  10.     *p = 10;  
  11.       
  12.     printf("%d\n", *p);   //10  
  13.     f(p);  //通过f()修改p指向内存的值  
  14.     printf("%d\n", *p); //p指向的内存已经释放,所以会出错  
  15.       
  16.     return 0;  
  17. }  
  1. /* 
  2.     2012年2月5日15:37:36 
  3.     动态一维数组示例 
  4. */  
  5. # include <stdio.h>  
  6. # include <malloc.h>  
  7.   
  8. int main(void){  
  9.     int a[5]; //包含20字节  
  10.     int i;  
  11.     int len;  
  12.     int *pArr;  
  13.       
  14.     printf("请输入你要存放的元素个数:");  
  15.     scanf("%d", &len);  
  16.     pArr = (int *)malloc(4*len);  //pArr指向前4个字节  类似于 int pArr[len];  
  17.     // pArr+1 就指向第5到第8个字节                     
  18.     //动态的构造了一个int类型的一维数组,数组名 pArr  
  19.     for (i=0; i<len; i++)  //对一维数组进行赋值  
  20.         scanf("%d", &pArr[i]);  
  21.           
  22.     printf("一维数组的内容是:\n");  
  23.     for(i=0; i<len; i++)  
  24.         printf("%d\n", pArr[i]);  
  25.       
  26.     return 0;  
  27. }  
  28. 输出结果:  
  29. 请输入你要存放的元素个数:5  
  30. 1 2 3 4 5  
  31. 一维数组的内容是:  
  32. 1  
  33. 2  
  34. 3  
  35. 4  
  36. 5  

三、静态内存和动态内存的比较

静态内存是由系统自动分配,由系统自动释放

静态内存是在栈中分配的

动态内存是由程序员手动分配,手动释放

动态内存是在堆中分配的

  1. # include <stdio.h>  
  2.   
  3. void f(int ** q){  
  4.     int i = 5;  
  5.     //*q 等价于p q 和**q都不等价于p  
  6.     *q = &i;  
  7. }  
  8. int main(void){  
  9.     int * p;  
  10.       
  11.     f(&p);  //访问完后释放内存  
  12.     printf("%d\n", *p); //本语句语法没有问题, 但逻辑上有问题  
  13.     //访问了不该访问的内存,f()函数结束后i的空间已经被释放  
  14.     //静态变量,不能跨函数使用,当函数结束后变量不能被访问  
  15.       
  16.     return 0;  
  17. }  
  1. # include <stdio.h>  
  2. # include <malloc.h>  
  3.   
  4. void f(int **q){  
  5.     *q = (int*)malloc(sizeof(int)); //动态分配内存  
  6.     //等价于 p = (int *)malloc(sizeof(int));  
  7.     **q = 5;  
  8. }  
  9.   
  10. int main(void){  
  11.     int * p;  
  12.     f(&p);  
  13.     printf("%d\n", *p); //f()结束后,p指向的动态内存没有释放  
  14.       
  15.     return 0;  
  16. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值