zoukankan      html  css  js  c++  java
  • 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(6)动态内存分配

    一、传统数组的缺点:

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

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

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

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

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

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

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

    二、动态分配

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

    举例:动态数组

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

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

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

    静态内存是在栈中分配的

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

    动态内存是在堆中分配的

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



  • 相关阅读:
    关于模式窗体的缓存问题的解决方案
    C# 读取网页
    C# 压缩文件
    C#实现反射调用动态加载的DLL文件中的方法
    在线程中修改窗体控件内容
    C# 启用双缓存,避免ListView控件加载数据时闪烁
    JBuilder2005破解方法
    C# combbox datatable 赋值
    今天感觉到秋凉了~
    烦人的流程图~~~
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469083.html
Copyright © 2011-2022 走看看