精华内容
下载资源
问答
  • 内存动态分配

    千次阅读 2020-01-30 21:17:07
    C库函数malloc,calloc,realloc,free的用法 *此博客仅用来记录博主的...分配所需的内存空间,并返回一个指向它的指针。(空类型,必要时可以转换) 参数(一个) size 内存块的大小,以字节为单位。 案例--...

    C库函数malloc,calloc,realloc,free的用法

                   *此博客仅用来记录博主的C语言学习路程,如果内容有帮到你,那我将感到十分的荣幸*
    

    malloc用法

    声明:
    void *malloc(size)
    
    分配所需的内存空间,并返回一个指向它的指针。(空类型,必要时可以转换)
    
    参数(一个)
     size
     
     内存块的大小,以字节为单位。
    
    • 案例---------用malloc动态创造一个数组
    #include<stdio.h>
    int main()
    {
    	int num;
    	printf("Please enter a number:__\b\b");
    	scanf_s("%d",&num);
    	int* p = (int *)malloc(sizeof(int) * num);
    	for (int i = 0; i < num; i++)//按照数组的方式访问
    	{
    		p[i] = i;
    		printf("%3d\n",p[i]);
    	}
    	free(p);//用完了一定要释放内存
    	return 0;
    }
    

    解释:以上的代码片用malloc函数动态分配了sizeof(int) * num个字节,因为malloc函数返回值是一个空指针的类型,所以我在上述代码中将其类型转换成(int *)类型的指针,并用int类型的指针变量p接收,因为num的值是用户输入的,所以下一步用一个for循环初始化一维数组,然后将其打印输出,最后释放内存,这一步必不可少,请读者务必注意,博主将在后文分析不释放内存的后果。

    calloc用法

    声明:
    void *calloc(nitems,size)
    
    参数(两个):
    nitems -- 要被分配的元素个数。
    size -- 元素的大小。(以字节为单位)
    
    • 案例1-------用calloc动态创造一个数组
    #include<stdio.h>
    #include<Windows.h>
    #include<stdlib.h>
    int main()
    {
    	int num;
    	printf("please enter a number:\n");
    	scanf_s("%d",&num);
    	/*double* p = (double*)malloc(sizeof(double) * num);*/
    	double* p = (double*)calloc(num, sizeof(double));//calloc用法跟malloc差不多,calloc前面两个参数相乘等于malloc的参数
    	for (double i = 0; i < num; i++)
    	{
    		p[(int)i] = i+1;//对于指针指向的内存,用下标访问
    		printf("%f\n",p[(int)i]);
    	}
    	free(p);//释放内存
    }
    

    解释:这次的案例跟上一个整体相当,但有两点不一样,第一个就是用calloc动态分配内存空间,另一个是创建了一个浮点型的数组,然后根据用户输入的num值循环初始化数组,生成1~num之间的数据,由于数组是浮点型的,但是数组的下标却是整型的,所以要进行一次类型转换,如上图,p[(int)i] = i+1,最后释放内存(千万别忘了!非常重要!!),至于callocmalloc有什么不一样,我们后面会慢慢分析。

    realloc用法

    声明:
    void *realloc(void *ptr, size_t size)
    
    尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小。
    
    参数:
    ptr --------- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc
     	          进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
     	   
    size -------- 内存块的新的大小,以字节为单位。
               如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。
    
    • 案例
    #include<stdio.h>
    #include<Windows.h>
    #include<stdlib.h>
    int main()
    {
    	int num;
    	printf("Please enter a number:__\b\b");//数组开始的长度
    	scanf_s("%d",&num);
    	int* p = (int*)malloc(sizeof(int) * num);
    	printf("初始地址是:%p\n",p);//打印初始地址-----由malloc分配
    	for (int i = 0;i<num;i++)//输出由malloc动态分配的数组
    	{
    		p[i] = i + 1;
    		printf("%d   %x\n",p[i],&p[i]);
    	}
    	int newnum;
    	printf("Please enter a number again:__\b\b");//数组增加后的长度
    	scanf_s("%d",&newnum);
    	int* p1 = (int *)realloc(p,newnum);//realloc返回值是一个空指针,这里将它转换成int型
    	printf("重新分配的地址是:%p\n",p1);//打印由realloc分配的地址,与malloc分配的相同
    	for (int i = 0; i < newnum; i++)//输出重新分配内存块的数组
    	{
    		p1[i] = i + 1;
    		printf("%d\n",p1[i]);
    	}
    	//free(p);
    	return 0;
    }
    

    解释:以上的代码主要分为两个部分,前半部分用malloc函数动态分配内存创造一个一维数组,但是有时候我们可能会觉得已经创造的数组长度不能满足我们的实际需要,我们想要扩大数组的长度怎么办?这个时候代码的后半部分就是解决这个问题的,realloc函数可以额外扩展内存,它主要通过两种方式扩展内存,具体细节我们稍后再谈,因为reallocmalloc函数和calloc函数一样,返回值是一个void类型的指针,但我们创造的数组是int类型的,因此在这里我们要进行一次类型转换,并用int类型的指针p1接收,然后我们用scanf_s重新定义改变后数组的长度,为了比较扩展内存后的数组与原数组的区别,我分别打印了扩展前和扩展后数组的首地址,结果是地址相同,最后,输出扩展内存后的数组

    malloccallocrealloc的区别

    	malloc,calloc都是分配内存
    
    
        malloc根据大小,calloc根据元素大小还有个数
        
    
    	malloc分配后不会初始化,calloc会把要分配的那块内存全部初始化为0
    	
    
    	realloc就是内存不够的情况下,扩展内存     
    

    malloccalloc的主要区别就是calloc会初始化要分配的那块内存,全部初始化为0

    阿堵物
    在这里插入图片描述

    在这里插入图片描述

    接下来我们转到调试里面打开内存窗口

    在这里插入图片描述

    在这里插入图片描述

    输入地址:0FFDC040

    在这里插入图片描述

    我们按照4字节整数,带符号来显示:

    在这里插入图片描述

    我们可以看到,指定区域里面全部被初始化为0

    • 案例
    #include<stdio.h>
    int main()
    {
    	/*
    		malloc,calloc都是分配内存,malloc根据大小,calloc根据元素大小还有个数
    
    		malloc分配后不会初始化,calloc会把要分配的那块内存全部初始化为0
    
    		realloc就是内存不够的情况下,扩展内存                                                                                            
    	*/
    	int num;
    	printf("Please enter a number:\n");
    	scanf_s("%d",&num);
    	int* p = (int*)malloc(sizeof(int) * num);//malloc动态分配
    	printf("初次动态分配的数组的首地址:%p\n",p);
    	for (int i = 0; i < num; i++)//初始数组
    	{
    		p[i] = i;
    		printf("%d\n",p[i]);
    	}
    	int newnum;
    	printf("请输入更改后数组的长度:");
    	scanf_s("%d",&newnum);
    	int* p1 = (int*)realloc(p,newnum);//realloc动态分配
    	/*
    		realloc重新分配内存,如果可以扩展就在原内存块的基础上往后扩展一部分区域;
    
    		扩展就是在原来地址后面增加内存
    		
    		否者重新开辟一片内存,并且回收原来的内存,而且在回收之前拷贝原来的内容
    	*/
    	printf("使用realloc动态分配后数组的首地址:%p\n",p1);
    	for (int i = num; i < newnum; i++)//增加长度后的数组
    	{
    		p1[i] = i;
    		printf("%d\n",p1[i]);
    	}
    	free(p1);//释放内存
    
    	return 0;
    }
    

    古人云:“无规矩不成方圆”

    虽然内存分配很方便,但凡事都要有个度,下面这个例子就是演示内存分配危害的例子
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    int main1()
    {
    	while (1)
    	{
    		void* p = malloc(1024*1024*100);//malloc返回空类型的指针,为其分配100M内存
    		Sleep(1000);
    		free(p);//根据地址释放内存
    		Sleep(1000);
    	}
    	return 0;
    }
    int main2()
    {
    	void* p = malloc(0xffffffff);//如何检测内存是否分配成功
    	if (p == NULL)//为空就是没有分配成功
    	{
    		printf("内存分配不成功\n");
    	}
    	return 0;
    }
    int main3()
    {
    	int*p=(int *)malloc(sizeof(int));//分配一个元素大小的字节
    	*p = 5;
    	printf("我有%d元\n",*p);
    	free(p);//释放内存
    	int* p1 = p;//内存根据地址来释放
    	free(p1);//内存不可以反复释放
    	return 0;
    }
    

    在这里插入图片描述
    在这里插入图片描述

    mian1函数演示了内存的定时分配与释放,如上图所示。

    在这里插入图片描述

    main2函数演示了如果分配的内存过大的话,会导致不成功,如上图所示

    在这里插入图片描述

    main3函数展示了内存不能反复释放

    free()函数根据地址来释放内存,即使重新定义了一个指针变量,但只要地址相同,就会报错
    

    所以,根据软件工程规范,释放内存后,将指针赋值为空

    free(p);
    p = NULL;
    

    但是有的人对释放后的内存充满了好奇,固执的还想要访问原来数组的元素,那么我们看看这将会发生什么事情
    在这里插入图片描述
    在这里插入图片描述
    此时指针的地址已经为0000000了,因为被赋值为NULL
    但是如果不小心没有赋值为NULL,而且又访问量原数组中的元素会产生什么呢?
    在这里插入图片描述
    就会产生一堆垃圾数据,毫无意义

    所以,综上分析,我们要做有意义的事情,不要给博主我添乱【Dog】

    展开全文
  • 有一些空闲内存,但是碎片化严重。怎样动态分配内存才能利用他们?(假设需要的空间大于每一个小碎片内存,小于内存之和)
  • 前言 本博文基于VC++6.0开发调试 ...什么是内存动态分配 C语言中的全局变量和局部变量分别分配内存的栈中的静态存储区和动态存储区,关于静态存储区和静态存储区之前的博客也有介绍, ...

    前言

    1. 本博文基于VC++6.0开发调试
    2. 只是对这四个函数的一个总结;
    3. 动态内存分配这个知识经常和动态数据链表(如链表)结合使用;

    什么是内存的动态分配

    C语言中的全局变量和局部变量分别分配内存的栈(stack) 中的静态存储区和动态存储区,关于静态存储区和动态存储区之前的博客也有介绍(https://blog.csdn.net/wuyuzun/article/details/82354885)
    在括号里的这篇博文里介绍过静态存储区和动态存储区内的变量是有生命周期的;全局变量被编译器编译时,开始分配其内存单元,生命周期持续到程序运行结束;局部变量比如函数参数,当程序被调用时为参数分配内存单元,函数调用结束生命周期也结束,所占用的内存单元被释放;那么除此之外还有一种情况,就是生命周期由用户自己决定,需要多少内存就开辟多少内存,用完了的时候释放就可以了,并且这些内存一般是用来存储一些临时数据,所以称为内存的动态分配,而这个存储区成为堆(heap)
    所以将C语言中常用的存储区分类:

    区名 生命周期 存储数据类型
    静态存储区 从定义处到程序结束 全局变量,静态变量(static)
    文字常量区 从定义处程序结束释放 常量字符串
    程序代码区 从开始执行程序的开始 ,到程序结束 二进制代码
    栈(stack) 一般为函数结束 函数参数值,临时变量,局部变
    堆(heap) 由程序猿开辟,由程序猿释放或程序结束释放 内存的动态存储区,存放程序运行中的临时数据

    注意:内存的动态分配是向系统申请内存空间,但是由于这个内存空间不像数组一样有数组名,所以对这段内存的读写都是靠指针来实现的

    怎样建立内存的动态分配

    系统提供的库函数:

    函数名 全称 功能
    malloc(n) 动态内存分配函数 在堆总开辟n个字节的存储空间
    calloc(n,m) 动态内存分配并清零函数 在堆中开辟n*m个字节空间(),为每个元素清零
    free§ 动态内存释放函数 释放指针p所指向的开辟的内存空间
    realloc(p,n) 动态内存调整函数 修改p所指向的动态内存空间为n个字节(p的值不变)

    **注意:**这些函数定义在库函数stdlib.h中,在使用时需要调用其头文件;

    动态内存分配函数malloc

    函数原型:void *malloc(unsigned int size);
    函数特点:

    1. 函数为无符号指针函数,返回值是不指向任何数据类型的此函数所开辟的内存空间的首地址;
    2. 参数为无符号整型,因为要开辟的内存空间数不会是负值;
    3. 如果开辟空间失败(内存不足或其他情况),函数返回值为NULL;
    4. 此段内存空间中的值为任意值,也就是没有进行初始化,memset函数可以完成对这个空间的初始化;
      举例:
    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
    	void *p = NULL;
    	p = malloc(100);
    	printf("%d\n",p);
    }
    

    运行结果:(这个地址是随机的,每次运行结果并不相同)
    在这里插入图片描述
    图像表示"p = malloc(100)":
    在这里插入图片描述

    动态内存分配并清零函数calloc

    函数原型:void *calloc(unsigned int n , unsigned int size);
    函数特点:

    1. 函数同样为空类型指针类型,返回的地址同样为所开辟空间的首地址,如果开辟失败,则返回NULL;
    2. 开辟的是一个数组空间,此数组一共n个元素,每个元素的存储字节数为size;
    3. 除了开辟空间之外,此函数还为每个元素赋初值为0;
    4. 函数calloc() 会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零.

    举例:

    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
    	void *p = NULL;
    	p = calloc(4,100);   //在栈中分配4个长度为100字节的内存空间;
    	printf("%d\n",p);
    }
    

    运行结果:(这个地址是随机的,每次运行结果并不相同)
    在这里插入图片描述
    图片解释“p = calloc(4,100)”:
    在这里插入图片描述

    动态内存释放函数free

    函数原型:void free(void *p);
    函数特点:

    1. 此函数用来释放指针p所指针的动态内存空间;
    2. 一般和malloc函数搭配使用;
    3. 一般free函数释放的是最近开辟的一个内存空间;
    4. 当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏.一部分的内存没有被使用,但是由于没有free,因此系统认为这部分内存还在使用,造成不断的向系统申请内存,使得系统可用内存不断减少.但是内存泄漏仅仅指程序在运行时,程序退出时,OS将回收所有的资源.因此,适当的重起一下程序,有时候还是有点作用.

    举例说明:

    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
    	void *p = NULL;
    	p = malloc(4,100);
    	printf("%d\n",p);   
    	free(p);    //需要注意的是,内存释放后,p本身的值并没有发生改变;
    }
    

    运行结果:(这个地址是随机的,每次运行结果并不相同)
    在这里插入图片描述

    动态内存调整函数realloc

    函数原型:void *realloc(void *p,unsigned int size)
    函数特点:

    1. 函数返回值为指针,如果操作失败(内存不足或其他)返回为NULL;
    2. 函数用来重新分配由malloc和calloc函数所开辟的首地址为p内存空间,修改其大小为size;
    3. 重新分配后,p的值可能会发生改变;
    4. 此函数是堆中开辟的内存;
    5. realloc是从堆上分配内存的.当扩大一块内存空间时,realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;如果数据后面的字节不够,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.这句话传递的一个重要的信息就是数据可能被移动.
    6. realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变.当然,对于缩小,则被缩小的那一部分的内容会丢失.realloc并不保证调整后的内存空间和原来的内存空间保持同一内存地址.相反,realloc返回的指针很可能指向一个新的地址.

    举例:

    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
    	void *p = NULL;
    	p = malloc(100);
    	realloc(p,120);
    	printf("%d\n",p);
    	free(p);
    }
    

    运行结果:(这个地址是随机的,每次运行结果并不相同)
    在这里插入图片描述
    图片解释“realloc(p,120)”:
    在这里插入图片描述
    但是realloc函数不仅可以增加拓展内存空间,还可以缩短内存空间;
    例如:realloc(p,80)代表:
    在这里插入图片描述
    注意:

    那么,这些内存的开辟干什么用哪?

    用来存临时数据, 而且是一般存储的数据往往都是有一定量的,但是这里有个问题:分配的临时存储空间内并没有数据类型,例如malloc开辟的空间,就只是一个由若干个字节组成的内存空间块,如何像数组一样去存储数据,并按照地址去访问它们?解决这个问题的办法是强制类型转换;并且有一点要说明的是,在C 99之前,malloc和calloc函数的数据类型是字符指针型(char *)的,但即使是这样,这些内存空间并不一定是用来存字符的;
    举例说明:

    #include <stdio.h>
    #include <stdlib.h>
    void main()
    {
    	void Chack(int *p);
    	int i,*p = NULL;
    	p = (int *) malloc(5*sizeof(int)); 
    	 /*
    	1.这里发生了强制性类型转化,但即使不进行强制转化,编译器也会进行默认转化
    	2.sizeof()函数解决了程序的健壮性和可已知项以及所开辟空间字节数和所转化数据类型的不匹配问题;
    	*/
    	printf("请输入5个人的成绩:\n");
    	for(i=0;i<5;i++)
    		scanf("%d",p+i);
    	Chack(p);
    	free(p);
    }
    void Chack(int *p)
    {
    	int i=0;
    	for(;i<5;i++)
    		if(p[i]<60)
    			printf("不合格的成绩有:%d\n",p[i]);
    }
    

    运行结果:
    在这里插入图片描述
    图片解释:“p = (int ) malloc(5sizeof(int)); ”
    在这里插入图片描述
    显然,所开辟的空间被转换成了数组一样的内存空间,并存储了数据,各个小存储区可以利用指针的算术运算存取;

    写博客途中有遇到一些问题,拜读过这位前辈的博客,写的很好,很有深度:
    https://blog.csdn.net/shuaishuai80/article/details/6140979

    展开全文
  • C语言-用指针实现内存动态分配

    千次阅读 2018-07-15 21:39:00
    在C语言中,动态分配内存是通过动态存储分配函数 malloc() 来实现的,其功能是: 在内存的动态存储区中分配一连续空间。若申请成功,则返回指向所分配内存空间的起始地址的指针;若申请内存空间不成功,则返回NULL...

    动态存储分配函数

    在C语言中,动态分配内存是通过动态存储分配函数 malloc() 来实现的,其功能是:

    • 在内存的动态存储区中分配一连续空间。若申请成功,则返回指向所分配内存空间的起始地址的指针;若申请内存空间不成功,则返回NULL(值为0)。
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int a[5]={10,15,8,9,6};
    
        int length;
        printf("请输入你想分配内存空间的个数:");
        scanf("%d",&length);
        int *p = (int *)malloc(sizeof(int)*length);  //指针变量p中存放的是动态分配内存块的起始地址
        *p=10; //相当于a[0]
        p[1]=15;  //相当于a[1]
        printf("%d  %d\n",*p,p[1]);
        return 0;
    }
    

    运行结果

    img_2df513b378124008e9b2009800f5d8dc.png
    image.png
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int length;
        printf("请输入你想分配内存空间的个数:");
        scanf("%d",&length);
        int *p = (int *)malloc(sizeof(int)*length);
        if(p==NULL){   // 检查内存分配是否成功
            printf("Unable to allocate memory.\n");
            exit(1);
        }
        //也可以把 p 当成一个普通数组来使用
        printf("请输入 %d 个数:",length);
        for(int i=0;i<length;i++)
            scanf("%d",&p[i]);
    
        //打印输出数组
        printf("你输入的数组为:\n");
        for(int i=0;i<length;i++)
            printf("%d\t",*(p+i));
        free(p); //释放分配的内存空间
        return 0;
    }
    

    运行结果

    img_c437e632fe11a42f5d0657ba2c003c2d.png
    image.png

    注意:

    • 在调用 malloc() 时,应该利用 sizeof 计算存储块大小,不要直接写数值,因为不同平台数据类型占用空间大小可能不同
    • 每次动态分配空间都必须检查是否成功,考虑到意外情况的处理
    • 虽然这里的存储块是动态分配的,但它的大小在分配后也是确定的。不要越界使用,尤其不能越界赋值,否则可能引起非常严重的错误

    动态存储释放函数

    动态存储分配函数 void free(void *p) 功能:

    • 释放同动态存储分配函数申请到的整块内存空间,p为指向要释放空间的首地址。如果p的值是空指针,则free什么都不做。该函数无返回值。

    注意:

    • 释放后不允许再通过该指针去访问已经释放的块,否则可能引起灾难性错误。
    展开全文
  • 1. C语言的函数malloc和free  (1) 函数malloc和free在头文件中的原型及参数  void * malloc(size_t size) 动态配置内存,大小有size...释放动态申请的内存空间,调用free()后ptr所指向的内存空间被收回,如果

    1.   C语言的函数malloc和free

     (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数

           void * malloc(size_t size)

    动态配置内存,大小有size决定,返回值成功时为任意类型指针,失败时为NULL。

           void  free(void *ptr)

    释放动态申请的内存空间,调用free()后ptr所指向的内存空间被收回,如果ptr指向未知地方或者指向的空间已被收回,则会发生不可预知的错误,如果ptr为NULL,free不会有任何作用。

    (2) C语言中典型用法

            T为任意数据类型

           T *p = ( T * )malloc( sizeof(T) * n)

           if(NULL= =p)

    {

           printf(“malloc fail!\n”);

           ……//相关资源收回的处理

           exit(-1);

    }

    … …//此过程不能改变指针p的指向

    free(p);

    注意:malloc后通常要对返回值进行判断,避免发生不必要的错误。

    (3) 内存说明

    malloc函数动态申请的内存空间是在堆里(而一般局部变量存于栈里),并且该段内存不会被初始化,与全局变量不一样,如果不采用手动free()加以释放,则该段内存一直存在,直到程序退出才被系统,所以为了合理使用内存,在不适用该段内存时,应该调用free()。另外,如果在一个函数里面使用过malloc,最好要配对使用free,否则容易造成内存泄露(没有将内存还给自由存储区)。

    2.  C++中的运算符new和delete

    new和delete是C++中的运算符,不是库函数,不需要库的支持,同时,他们是封装好的运算符。

    (1)new是动态分配内存的运算符,自动计算需要分配的空间,在分配类类型的内存空间时,同时调用类的构造函数,对内存空间进行初始化,即完成类的初始化工作。动态分配内置类型是否自动初始化取决于变量定义的位置,在函数体外定义的变量都初始化为0,在函数体内定义的内置类型变量都不进行初始化。

    (2)delete是撤销动态申请的内存运算符。delete与new通常配对使用,与new的功能相反,可以对多种数据类型形式的内存进行撤销,包括类,撤销类的内存空间时,它要调用其析构函数,完成相应的清理工作,收回相应的内存资源。

    (3)典型用法

    int *p = new int;                       delete p;

    char *p = new char;                  delete p;

    类的类型 *p = new 类的类型; delete p;

    //注意,指针p存于栈中,p所指向的内存空间却是在堆中。

                                Obj * p = new Obj[100];                     delete [ ]p;

    //注意,new申请数组,delete删除的形式需要加括号“[ ]”,表示对数组空间的操作,总之,申请形式如何,释放的形式就如何。

    (4)内存说明。new申请的内存也是存于堆中,所以在不需要使用时,需要delete手动收回。

    3.  new/delete与malloc/free之间的联系和区别

    (1)          malloc/free和new/delete的联系

    a)存储方式相同。malloc和new动态申请的内存都位于堆中。申请的内存都不能自动被操作系统收回,都需要配套的free和delete来释放。

    b)除了带有构造函数和析构函数的类等数据类型以外,对于一般数据类型,如int、char等等,两组动态申请的方式可以通用,作用效果一样,只是形式不一样。

    c)内存泄漏对于malloc或者new都可以检查出来的,区别在于new可以指明是那个文件的那一行,而malloc没有这些信息。

    d)两组都需要配对使用,malloc配free,new配delete,注意,这不仅仅是习惯问题,如果不配对使用,容易造成内存泄露。同时,在C++中,两组之间不能混着用,虽说有时能编译过,但容易存在较大的隐患。

    (2)          malloc/free和new/delete的区别

    a)malloc和free返回void类型指针,new和delete直接带具体类型的指针。

    b)malloc和free属于C语言中的函数,需要库的支持,而new/delete是C++中的运算符,所以new/delete的执行效率高些。C++中为了兼用C语法,所以保留malloc和free的使用,但建议尽量使用new和delete。

    c)在C++中, new是类型安全的,而malloc不是。例如:

    int* p = new char[10];                    // 编译时指出错误

      delete [ ]p;                                     //对数组需要加中括号“[ ]”

    int* p = malloc(sizeof(char )*10);    // 编译时无法指出错误

       free (p);                                       //只需要所释放内存的头指针

    d)使用new动态申请类对象的内存空间时,类对象的构建要调用构造函数,相当于对内存空间进行了初始化。而malloc动态申请的类对象的内存空间时,不会初始化,也就是说申请的内存空间无法使用,因为类的初始化是由构造函数完成的。delete和free的意义分别于new和malloc相反。

    e)不能用malloc和free来完成类对象的动态创建和删除。

    4.  C/C++程序的内存分配介绍

    该部分参考于http://blog.csdn.net/sparkliang/archive/2008/12/30/3650324.aspx

     

    (1)栈内存分配运算内置于处理器的指令集中,一般使用寄存器来存取,效率很高,但是分配的内存容量有限。一般局部变量和函数参数的暂时存放位置。

    (2)堆内存,亦称动态内存。如malloc和new申请的内存空间。动态内存的生存期由程序员自己决定,使用非常灵活。

    (3)全局代码区:从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

    (4)常量区:文字常量分配在文字常量区,程序结束后由系统释放。

    (5)代码区:存放整个程序的代码,因为存储是数据和代码分开存储的。

     

    总结:

    (1)new、delete 是操作符,只能在C++中使用。malloc、free是函数,可以覆盖,C、C++中都可以使用。
    (2)new 自动计算需要分配的空间大小,可以调用对象的构造函数,对应的delete调用相应的析构函数。malloc仅仅分配内存,free仅仅回收内存,并不执行构造和析构函数
    (3)new 类型安全、返回的是某种数据类型指针,malloc 非类型安全、返回的是void指针。
    展开全文
  • 要实现动态分区分配,需要考虑三个方面的问题。分别是数据结构、分区分配算法、分区的分配与回收操作。 首数据结构 这里我们使用的是空闲分区链,采用双向链表表示空闲分区。 具体实现如下: typedef struct ...
  • malloc是C语言最常用的标准库函数之一,用于在程序运行中动态地申请内存空间。我们都会使用它,其函数原型为: extern void *malloc(unsigned int num_bytes); 那么它是怎么实现的呢?如果让我们自己实现malloc功能...
  • http://www.amobbs.com/thread-4516795-1-1.html
  • //定义一个内存作业区 class Area {  private int id;  private int value;  public int getId() {  return id;  }  public void setId(int id) {  this.id = id;  }  public int ...
  • 在C中动态分配内存的基本步骤有: 1,用malloc类的函数分配内存; 2,用这些内存支持应用程序 3,用free函数释放内存 二、动态内存分配函数  malloc :从堆上分配内存  realloc : 在之前分配的内存块的基础上,将内存...
  • 动态分配内存

    千次阅读 2016-08-23 16:26:57
    动态分配内存 所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,...
  • 问:为什么要动态分配内存 答1:因为内存太宝贵。 答2:如果全部是静止内存不能释放,对于小的程序可以运行完毕。但是对于大的程序,还没运行完,内存就要被占用完,此时就要发生内存泄露。 答3:给定一个占用...
  • 静态内存分配动态内存分配

    千次阅读 2019-05-25 14:05:02
    静态内存分配动态内存分配 动机 平时看c/c++的书籍时,总会看到一种观点,说是C/C++语言使用的时候动态内存分配是最重要的,使用malloc等函数分配内存必须要释放,否则及其容易出现内存泄露。但是自己有时候挺...
  • C语言中动态分配内存

    千次阅读 2013-10-27 10:07:09
    什么是内存动态分配:全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个称为栈的区域。所谓动态分配内存指的是C语言允许建立内存动态分配区域,...
  • 静态内存分配动态内存分配小结

    千次阅读 2019-05-24 22:01:09
    静态内存是由系统自动分配内存,由系统自动释放。静态内存是在栈中分配的,假如main函数调用另一个函数,那么就把被调用函数压到一个栈里面。执行这个被调函数就是使系统为这个函数分配的所有内存空间逐个出栈。出栈...
  • 简单理解动态内存分配和静态内存分配的区别

    千次阅读 多人点赞 2015-06-22 13:38:22
    在涉及到内存分配时,我们一般都要考虑到两种内存分配方式,一种是动态内存分配,另一种是静态内存分配,我们该怎么理解这两者的区别呢? 在我看来,静态内存分配动态内存分配比较典型的例子就是数组和链表,数组...
  • C语言动态分配内存

    万次阅读 2018-06-18 15:45:24
    C语言动态分配内存 malloc 动态开辟内存的函数: void* malloc (size_t size); 这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针 如果开辟成功,则返回⼀个指向开辟好空间的指针 如果开辟...
  • C语言动态内存分配函数

    万次阅读 多人点赞 2019-06-02 23:46:57
    目录 1.malloc()2.free()3.calloc()4.realloc()5....所开辟的内存是在栈中开辟的固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 因为数组的内存是在编译时分配好的 . 如果我们想在...
  • c语言 动态内存分配

    千次阅读 多人点赞 2021-02-25 13:58:48
    动态内存分配数据类型总览内存分配1 整形内存分配2浮点数内存分配 数据类型总览 内存分配 1 整形内存分配 原码: 直接将二进制按照正负数的形式翻译成二进制。其中最高位为符号位 正数为1 负数为0. 反码: 将原码...
  • 动态内存分配函数

    千次阅读 2018-03-28 21:43:28
    一、静态存储分配动态存储分配: 二、动态内存分配函数 malloc calloc realloc free new delete
  • 动态分配内存与静态内存

    千次阅读 2016-06-03 22:23:22
    1) 静态内存分配是在编译时完成的,不需要占用CPU资源;动态分配内存是在运行时...4) 静态分配内存需要在编译前确定内存块的大小,而动态分配内存不需要编译前确定内存大小,根据运行时环境确定需要的内存块大小,按照
  • 为了动态的管理宝贵的内存,许多程序中要使用到动态内存分配。一般情况下,在c语言中,使用malloc()函数来分配指定大小的内存空间,用free()函数来释放这块内存空间。但是,往往初学者在编写这类程序时会出错,而...
  • C/C++ 动态内存分配

    万次阅读 多人点赞 2019-06-30 18:03:06
    首先我们看看 c 语言是如何进行动态内存分配的; c 语言主要是使用malloc / calloc / realloc 来进行内存申请的。 malloc / realloc / calloc三者的共同点与不同点: 共同点 1、都是从堆上进行动态内存分配 2、...
  • 堆栈与动态分配内存空间

    千次阅读 2017-11-04 14:30:55
    C/C++的动态分配内存空间。
  • 首先,在使用动态分配内存技术前,必须明白自己在做什么,这样做与其它的方法有什么不同,特别是会产生哪些负面影响,天下没有免费的午餐。动态分配内存与静态分配内存的区别: 1) 静态内存分配是在编译时完成的,不...
  • c语言动态内存分配

    千次阅读 2019-01-03 23:00:21
    动态内存分配是许多高级程序设计技巧的关键。 所有程序都必须留下足够的内存来存储程序使用的数据。这些内存中,有些是自动分配的(栈),有些是在编译时就确定好的(静态区),c语言还可以实现动态的/运行时的内存...
  • 动态存储器分配器的概念讲在前面:这个和c语言中的malloc和free有关。主要是了解内存动态分配方式。
  • 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译器分配内存,它的分配是在程序开始...动态内存:指在程序执行的过程中动态分配或者回收存储空间的分配内存的方法。 1.下面通过一个例

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 513,644
精华内容 205,457
关键字:

内存的动态分配