首页 > 其他分享 >malloc,calloc,realloc函数详解

malloc,calloc,realloc函数详解

时间:2023-03-23 22:32:06浏览次数:37  
标签:返回 malloc 函数 int realloc 空间 地址 calloc include

首先从思维导图大概了解一下malloc,realloc和calloc函数

malloc,calloc,realloc函数详解_#include

1.malloc函数

malloc,calloc,realloc函数详解_c函数_02

函数功能:malloc能从堆区申请空间给与我们使用,同时返回那片空间所处的首位置的地址。从图我们也能看到malloc返回的为void*类型的指针。

我们从下面的代码来了解这个函数


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
	//申请空间
	int* a = (int*)malloc(20);//这个代码malloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
	{
		printf("error:%s", strerror(errno));
    return 0;//当空间创建失败的时候也就不用再继续执行代码了所以提前返回
	}
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
	}
	for (int i = 0; i < 5; i++)
	{
		printf("%d", a[i]);
	}
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

代码运行结果:

malloc,calloc,realloc函数详解_c函数_03

当我将上面的malloc创建的空间改为2000000000000000000运行结果就会

malloc,calloc,realloc函数详解_i++_04

如果不进行判断那么就可能出现问题,所以判断空间是否开辟成功是不可或缺。

总结:使用malloc函数创建空间的时候要注意返回值要强制类型转换,否则无法使用还有每一个内存

创建函数创建空间后,使用完空间后要释放空间,同时将指向那片空间的指针赋值为空指针。

2.calloc

函数功能:和malloc函数一样但是会将创建的空间里面的值全部初始化为0

malloc,calloc,realloc函数详解_c函数_05

这是上面的那个代码运行后a,以及里面所储存的值地址可以看到地址指向的空间里面所储存的值为-842150451,这就是编译器在创建空间时默认给的值,可见malloc函数并不会将所创建的空间里面的值给初始化,但是calloc就会

malloc,calloc,realloc函数详解_#include_06

同样是创建20个字节大小的空间:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
	//申请空间
	int* a = (int*)calloc(5,sizeof(int));//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
	}
	for (int i = 0; i < 5; i++)
	{
		printf("%d", a[i]);
	}
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

cealloc运行可见cealloc创建的空间会被初始化为0

malloc,calloc,realloc函数详解_c函数_07

3.realloc

malloc,calloc,realloc函数详解_c函数_08

函数功能:修改ptr指向的空间大小,修改为size字节的大小。

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
	}
	int* pc=(int*)realloc(a, 40);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	//
	if (pc == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	a = pc;
	for (int i = 5; i < 10; i++)
	{
		a[i] = i + 1;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

运行结果:

malloc,calloc,realloc函数详解_c函数_09

接下来我们思考以下问题:

1.realloc创建的新空间是否被初始化过呢?

malloc,calloc,realloc函数详解_#include_10

从图我们能知道很明显并没有。

2.既然realloc会扩大空间那么如果扩大后的空间会占用其它函数创建的空间,那么此时realloc函数又会返回那里的地址呢?

验证代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
	}
	int* pc=(int*)realloc(a, 4000000000);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	//
	if (pc == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	a = pc;
	for (int i = 5; i < 10; i++)
	{
		a[i] = i + 1;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

下面的图片是我调式得来的,此时运行到了刚刚扩大新空间

从这我们就能知道realloc确实扩大了空间不过不是从原空间开始扩展的,而是换了一个有这么多大小并且不会占用其它函数空间的空间,并且返回了那个新空间的首地址

malloc,calloc,realloc函数详解_i++_11

但是如果我们执行下面的代码又会发现不同情况

验证代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
	}
	int* pc=(int*)realloc(a, 40);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	//
	if (pc == NULL)
	{
		printf("error:%s", strerror(errno));
		return 0;
	}
	a = pc;
	for (int i = 5; i < 10; i++)
	{
		a[i] = i + 1;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

可见此时realloc返回的值还是原来空间的地址,因为此时这片空间可以扩大到我们要求的大小,并且不会占据其它函数空间,所以返回了原来的地址。

malloc,calloc,realloc函数详解_#include_12

由此我们也就能知道:

realloc函数当原空间能扩大到我们所要求的大小并且不会占据其它函数的空间,那么它就会返回原来空间的地址,但是当原空间不能扩大到我们所要求的大小或是会占据其它函数的空间之时,reallco就会释放原空间并去找到一个新空间能满足我们的要求并且不会占据其它函数空间,之后返回这片新空间的首地址。

这篇文章就写到这里了,希望能对阅读的你有所帮助,如果发现任何错误,请严厉指出,我一定虚心接收并且改正。

标签:返回,malloc,函数,int,realloc,空间,地址,calloc,include
From: https://blog.51cto.com/u_15838996/6146007

相关文章

  • 虚拟内存与malloc/new原理详解
    mallocmalloc()函数并不是系统调用,而是C库里的函数,用于动态分配内存。malloc()分配的是虚拟内存,而不是物理内存。如果分配后的虚拟内存没有被访问的话,是不会将虚拟内存......
  • 使用malloc创建空间是否需要对返回值进行强制转换
    先说结论,对是malloc()函数的返回值是否进行强制转换取决于程序的编译环境。在C中,强制转化是在画蛇添足;在C++中强制转换是必须的。如果说在C环境和C++环境之间进行移植,建议......
  • malloc--候捷老师
    内存分配:动态内存分配器维护着一个进程的虚拟内存区域,堆。设计:分段管理(方便归还group给操作系统),bitmap设计,多对双向链表负责不同大小内存块管理,嵌入式指针,缓式回收。......
  • 有什么区别 new 和 malloc() ?
    malloc()是一个以数字(字节)作为参数的函数;它返回一个void*指向单元化存储。new是一个运算符,它接受一个类型和(可选)该类型的一组初始值设定项作为它的论点;它返回一个......
  • malloc、calloc、realloc的区别
    malloc、calloc、realloc的区别1、C语言跟内存分配方式<1>从静态存储区域分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量、stat......
  • linux源码解析06–常用内存分配函数kmalloc、vmalloc、malloc和mmap实现原理
    1.kmalloc函数static__always_inlinevoid*kmalloc(size_tsize,gfp_tflags){ if(__builtin_constant_p(size)){#ifndefCONFIG_SLOB unsignedintindex;#end......
  • malloc、calloc和realloc的区别
    1.malloc函数使用方法:参数是所需申请的内存块的字节数,返回指向申请的内存块的首地址的无类型指针,malloc申请的内存块是未初始化的。函数原型:void*malloc(size_tnum_s......
  • new和malloc的区别
    从表层调用来看:1.名称/语法一个是操作符,一个是调用函数(cdecl)int*v1=newint;//无需指定内存块的大小int*v2=(int*)malloc(sizeof(int));//需显式指出内存块的......
  • c分配内存底层函数 realloc
    realloc(void*__ptr,size_t__size):更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。如果将分配的内存减少,realloc仅仅是改变索引的信息。如果是将......
  • C++ malloc下申请内存途径
    之前就因为glibc的free不一定会将内存归还OS,导致OOM,造成了上千万损失,当时心态差点崩了五年前的时候,因为OOM导致进程无故被kill掉,也没有coredump,分析了好久,最后发现是因为......