realloc和malloc和calloc的区别和用法 ---12.4 个人学习笔记

realloc和malloc和calloc的区别和用法(个人学习笔记)

思路:先讲下realloc  malloc  和 calloc 有啥用法

有一点需要说明的是,他们都是用来开辟内存空间的,其中malloc是在栈区中分配一个内存空间,calloc与realloc都

是在堆区中分配内存的。访问栈中的内存一般都会比堆区的快,但是有一点是,栈区的内存容量是比较小的,因此要

注意栈区的内存溢出等问题和越界等问题。

 

在我们学习的时候一般都是先接触的是malloc  然后再接触calloc和realooc

所以思路:malloc -- > calloc --->realloc 

 

malloc

原型:void* malloc(unsigned size); void* calloc(size_t nelem, size_t elsize); 
用法:#include <stdlib.h> 
功能:在堆区开辟一个可控的内存
说明:size 为需要分配的内存空间的bai大小,以字节(Byte)计。如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 
当内存不再使用时,应使用free()函数将内存块释放。 
注意:这个是开辟的是一个新的未初始化的内存,要注意初始化和赋值

#include <stdio.h>
#include <windows.h>


void TextMalloc()
{								/*由于malloc 返回的是void*类型 或者  unsigned int 类型*/ 
	int * p = (int*)malloc(10*sizeof(int)) ;  // 在这里申请使用内存,(int*)转换成int*类型 
	int i;
	for (i = 1; i< 10;i++)
	{
		p[i] = i;
		printf("%d\n",p[i]);
	}
	
	
	free(p);
}

int main(void) 
{
	
	TextMalloc();
	
	system("pause");
}

用malloc的时候要注意的几点是:

1.返回的是开辟空间的首地址

2.返回的类型是void* 类型  ,可以随便转换类型,所以灵活使用,使用完要返还给内存,用free函数

3.不仅能开辟常用类型(int char double等),还能开辟组合类型(结构体等)

4.申请不一定成功,该函数申请失败返回NULL,故判断空间指向指针为NULL是申请不成功,不能使用   // 可以以下代码用来检测

	if (p != NULL)
	{
		free(p);
        printf("OK\n");
	 } 

5.即使我们用了free函数将指针所指向空间释放了,但是指针还保留有开辟空间的起始地址,当我们进行解引用时,就会产生指针所指空间不属于自己,但我们去使用了,导致一些未知性错误(free后指针置NULL)

	if (p != NULL)
	{
		free(p);
		printf("OK\n");
	 } 
	p = NULL ; // 置空 

6.动开辟的空间是连续的,同数组一样使用,都要防止越界访问      如下

void Text() 
{

    int* p=(int *)malloc(10*sizeof(int));
    int i=0;
    for(i=0;i<10;i++)
    {
    *(p+i)=i;
    }
    if(p==NULL)
    {
        printf("%s\n",strerror(errno));
        exit(1);
    }
    free(p);
    p=NULL;
    if(p==NULL)
    {
        printf("%s\n",strerror(errno));
        exit(1);
    
}
}

int main(void) 
{
	
	// TextMalloc();
	Text();
	
	
	system("pause");
}

calloc

1.函数原型:void *calloc( size_t num, size_t size );

2。malloc 的注意事项也同样适用(如上),只不过calloc多了一个参数size_t num,

还有一个就是calloc分配了内存之后会将所分配的内存空间置零。(和malloc相比省

去了一个menset()函数)

int* p=(int *)calloc(10,sizeof(int));    // 前面的10是分配的个数,后面的是分配的大小

char* cp=(char*)=calloc(100,sizeof(char));

其他的就和malloc一样的啦

realloc 
原型:extern void *realloc(void *mem_address, unsigned int newsize); 
用法:#include <stdlib.h> 有些编译器需要#include <alloc.h> 
功能:改变mem_address所指内存区域的大小为newsize长度。 
说明:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 
当内存不再使用时,应使用free()函数将内存块释放。 
注意:这里原始内存中的数据还是保持不变的。 

由于个人的表述能力不行,附上一个大牛 的解释

1、如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address 
这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。 
2、如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。 
并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。 
老块被放回堆上。 

具体的代码就是这样子的

// realloc.c 
#include <syslib.h> 
#include <alloc.h> 
main() 
{ 
char *p; 
clrscr(); // clear screen 
p=(char *)malloc(100); 
if(p) 
printf("Memory Allocated at: %x",p); 
else 
printf("Not Enough Memory!/n"); 
getchar(); 
p=(char *)realloc(p,256); 
if(p) 
printf("Memory Reallocated at: %x",p); 
else 
printf("Not Enough Memory!/n"); 
free(p); 
getchar(); 
return 0; 
} 
#include <malloc.h> 
char *p,*q; 
p = (char * ) malloc (10); 
q=p; 
p = (char * ) realloc (p,20); 

// 这里我要进行补充的是 

relloc 和 malloc 返回都是void * 类型,但是realooc需要一个类型转换(这一点和malloc有点不一样,malloc在有的编译器里会自动给你进行类型转换)

在一位CSDN大佬(我的算不算)的文章中一小段摘要中:

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>
#include <windows.h>

/*realloc原型是extern void *realloc(void *mem_address, unsigned int newsize);*/
/*指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。*/
void TextRelloc()
{
	int aaa ;
	int *num3 = (int*)malloc(sizeof aaa);
	int i ;
	for (i = 0;i< 10;i++)
	{
		num3[i] = i;
	}
	int *num = (int*)realloc(num3,10*sizeof(char));
	for (i = 0;i< 10;i++)
	{
		printf("%d\n",num3[i]);		/*得到的结果是0 但是要知道,malloc是不会置于0的*/ 
	}
	free(num3);
 } 
 
/*malloc 和 calloc 都是在栈区分配空间的,relloc是在堆区分配空间的*/

int main(void)
{	
    TextRelloc();
	
	
	system("pause");
}

假设整个堆其中都没有不论什么一处的内存可以满足realloc的需求。则此次分配失败,返回值为NULL。,可以看到我给定的内存空间太大导致分配不成功,后面的代码失效

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值