• C语言之内存管理


    动态内存分配

    传统数组的缺点

    1.数组长度必须事先指定,而且只能是常整数,不能是变量。

    代码示例

    例子int a[5]; 	//必须事先指定,而且只能是常整数int len = 5; int a[len];//error
    

    2.传统形式定义的数组,该数组的内存程序员无法手动释放数组一旦定义,系统为数组分配的内存空间就会一直存在,除非数组所在的函数运行终止,数组的空间才会被系统自动释放(不是清零)。。

    void f(void)
    {
        //数组a 占20个字节的内存空间,无法手动编程释放它,数组a只能在f()函数结束被系统释放 
    	int a[5]={1,2,3,4,5};
    } 
    

    3、数组的长度一旦定义,数组长度就不能再更改。

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

    4、传统方式定义的数组不能跨函数使用 。

    A函数定义的数组,只有在A函数运行期间才可以被其他函数使用。
    但A函数运行完毕后,A函数中的数组将无法在被其他函数使用。
    

    代码示例

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

    动态内存分配

    很好的解决的了传统数组的4个缺陷 ( malloc的使用 )

    代码示例

    # include <stdio.h>
    # include <malloc.h>
    #include <string.h>
    
    void test()
    {
        int * p = NULL;
        p = (int *)malloc(sizeof(int)); 
    
        if(p == NULL){
            perror("malloc");
            return ;
        }
        //清空空间
    	memset(p, 0, sizeof(int));
    
        *p = 10;
        printf("*p=%d
    ", *p);
    
        free(p); // 释放
    }
    
    int main()
    {
        // 调用函数
        test();
        return 0;
    }
    

    malloc实现图解

    图示:

    代码示例

    # include <stdio.h>
    # include <malloc.h>
    
    void fmin(int * q)
    {
    	//*p = 200; //error
    	//q = 200; 	//200不是整型变量的地址,q只能存放整型变量的地址
    	//**q = 200;  //error
    	*q = 200;
    	//free(q);  //把q所指向的内存释放掉  本语句必须的注释掉,否则会导致第20行的代码出错
    }
    
    int main(void)
    {
    	int * p = (int *)malloc(sizeof(int)); //sizeof(int)返回值是int所占的字节数
    	*p = 10;
    
    	printf("%d
    ", *p);  //10
    	fmin(p);  //p是int *类型
    	printf("%d
    ", *p);  //200    第20行
    
    	return 0;
    }
    

    图解

    动态一维数组示例

    代码示例

    # include <stdio.h>
    # include <malloc.h>
    
    int main(void)
    {	//如果int占4个字节的话,则本数组总共包含有20个字节,每四个字节被当做了一个int变量来使用
    	int a[5]; 
    	int len;
    	int * pArr;
    	int i;
    
    	//动态的构造一维数组
    	printf("请输入你要存放的元素的个数: ");
    	scanf("%d", &len);
        
        /*
    	本行动态的构造了一个一维数组, 该一维数组的产度是len, 该数组的数组名是pArr.
    	该数组的每个元素是int类型  类似于 int pArr[len];
        */
    	pArr = (int *)malloc(4 * len);  
    	
    	//对一维数组进行操作,  如:对动态一维数组进行赋值
    	for (i=0; i<len; ++i)
    		scanf("%d", &pArr[i]);
    
    	//对位一维数组进行输出
    	printf("一维数组的内容是:
    ");
    	for (i=0; i<len; ++i){
    		printf("%d
    ", pArr[i]);
        }
    		
    	free(pArr); //释放掉动态分配的数组
    	
    	return 0;
    

    图解动态一维数组

    动态数组的优点

    1.动态数组长度不需要事先给定;
    
    2.内存空间可以手动释放。
    
    3.在程序运行中,动态内存空间大小可以通过realloc函数手动扩充或缩小
    

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

    - 静态内存是由系统自动分配,有系统自动释放
    - 静态内存是在栈分配的		
    		
    - 动态内存是由程序员手动分配、手动释放
    - 动态内存是在堆分配的
    
  • 相关阅读:
    高考,高中毕业之后,这人世间,又多了一只闲云野鹤
    玩转Android之Drawable的使用
    Spring核心技术(七)——Spring容器的扩展
    商业研究(21):活力蛙,足疗O2O,曾经的“中国上门足疗领先品牌”
    商业研究(21):活力蛙,足疗O2O,曾经的“中国上门足疗领先品牌”
    【Raspberry Pi】DHT11 温度湿度传感器数据读取
    【Raspberry Pi】读取DHT11温度湿度波折
    【Raspberry Pi】webpy+mysql+GPIO 实现手机控制
    【python】正则表达式
    【Raspberry Pi】GPIO-发光二极管控制
  • 原文地址:https://www.cnblogs.com/Guard9/p/12905136.html
Copyright © 2020-2023  润新知