b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

malloc,calloc,realloc函数的用法,原理和不同的分析

电脑杂谈  发布时间:2020-03-24 08:06:41  来源:网络整理

calloc malloc_calloc函数与malloc_malloc realloc calloc

容器云强势上线!快速搭建集群,上万Linux镜像随意使用

I. malloc

MSDN中的malloc原型是:

无效* malloc(size_t大小);

简介:

malloc返回指向分配空间的空指针,如果没有足够的可用内存,则返回NULL. 要返回指向非void类型的指针,请对返回值使用类型强制转换. 返回值所指向的存储空间可以保证适当对齐以存储任何类型的对象. 如果size为0,则malloc在堆中分配零长度的项目,并返回指向该项目的有效指针. 始终检查malloc的返回结果,即使请求的内存量很小.

可能意味着:

malloc返回一个指针. 如果未成功分配内存或内存不足以导致分配失败,则会返回NULL指针. 否则,将返回分配的内容的第一个地址.

我应该在这里注意: 如果在malloc中将0写入size大小,它将向该变量写入0字节.

这里有歧义.

如果我向程序中编写了这样的代码行:

int * p;
p = (int *)malloc(0);

p的值是NULL吗?

由VS2013测试,它不是NULL. 为什么会这样?

MSDN中有这样一段:

malloc函数分配至少大小为字节的内存块. 由于对齐和维护信息所需的空间,该块可能大于大小字节.

这意味着malloc生成的空间量大于您编写的空间.

说明如下:

第一:

在标准的malloc实现中,不检查输入值的大小,但是在对齐后直接从堆中分配输入值.

第二:

不管输入值的大小如何,malloc的最小内部内存分配大小都是固定值(通常为8B),因为malloc需要此空间来维护堆上内存块的链表. 因此,当用户申请0B空间时,malloc分配的实际空间为8B. 如果用户请求的空间为X,则malloc分配的实际空间为(align(X)+ 8). 这就是为什么不能超出范围使用malloc分配的空间的原因: 堆的内部链表结构将被破坏.

实际上,在内存中是这样的:

那么,free是怎么知道要释放多少内存的呢?
看图~
malloc自动记录了此次分配的内存大小。

calloc malloc_malloc realloc calloc_calloc函数与malloc

其次,calloc

calloc的作用是什么?

calloc在MSDN中的描述如下:

calloc

在内存中分配一个数组,并将其元素初始化为0.

void * calloc(size_t num,size_t大小);

常规例程标头兼容性

calloc

int *p = (int*)calloc(0,2*sizeof(int));
//相当于
int *p=(int *)malloc(2*sizeof(int));
memset(p,0,2*sizeof(int));

为什么我们在日常生活中看到malloc比calloc更多?由于calloc会初始化内存空间,因此也会降低程序的效率.

在某些情况下,没有必要初始化内存空间〜

三,重新分配

ANSI C说明了用于动态分配存储空间的三个功能

(1)malloc分配指定数量的内存字节. 该存储区域中的初始值不确定

(2)calloc是指定长度的对象,并分配可以容纳指定数量对象的存储空间. 该空间中的每一位都初始化为0

(3)重新分配更改先前分配的区域的长度(增加或减少). 当增加长度时,可能需要将先前分配的区域的内容移动到另一个足够大的区域,并且新添加区域中的初始值不确定.

这是以上三个功能之间的区别

realloc分配失败时,返回NULL
realloc分配失败时,原来的内存空间不改变,不释放也不会移动
如果size=0,realloc = free,只对指针指向内存进行释放
对于二级指针来说,realloc(**p,0),只会释放一维指针,不会释放内存,所以要注意内存泄露
传递给realloc的指针必须是经过malloc,calloc,realloc申请的
当ptr为NULL,realloc(ptr,10) = malloc(ptr,10)

realloc允许我们增加或减少先前分配的区域的长度(最常见的用法是增加区域).

PS: Realloc用于增加动态序列表的容量.

如果首先分配一个可以容纳长度为512的数组的空间并在运行时填充它,但是发现空间不足,则可以调用realloc扩展存储空间.

1. 如果存储区后面有足够的空间用于扩展,则可以将原始存储区扩展到高地址方向,并返回传递给它的相同指针值.

2. 如果原始存储区之后没有足够的空间,则realloc会分配另一个存储区,该存储区足够大,可以将现有5 1 2元素数组的内容复制到新分配的存储区.

由于该存储区可能会移动,因此您不应在其中使用任何指针.

malloc realloc calloc_calloc malloc_calloc函数与malloc

注意

realloc的最后一个参数是存储区的newsize(新长度),而不是新旧长度之间的差.

作为一种特殊情况,如果ptr是一个空指针,则realloc具有与malloc相同的功能,并用于分配指定大小的存储区newsize.

四,阿洛卡

分配函数

还有另一个值得一提的功能,这就是alloca. 其调用顺序与malloc相同,但是它在当前函数的堆栈帧上而不是堆上分配存储空间.

优点是当函数返回时,它会自动释放它使用的堆栈帧,因此您不必担心释放空间. 缺点是某些系统在调用函数后无法增加堆栈帧的长度,因此它们无法支持alloca函数. 但是,许多软件包仍使用alloca功能,并且许多系统都支持它.

_alloca

在堆栈上分配内存.

void * _alloca(size_t大小);

常规例程标头兼容性

_alloca

=============================================== === =======

对于这个烂问题,请记下理解力. 这三个都在stdlib.h库中分配内存和所有函数,但是有一些细微的差异.

首先,对于malloc函数. 其原型void * malloc(unsignedintnum_bytes)

num_byte是要应用的空间大小,我们需要手动计算它,例如int * p =(int *)malloc(20 * sizeof(int)). 如果编译器默认将int设置为4字节,则计算结果为80Byte,一次应用一个

80个字节的连续空间,并且空间基地址被强制为int类型并分配给指针p. 此时,应用的内存值不确定.

对于calloc函数,其原型为void * calloc(size_t n,size_t大小);

从直觉上讲,它比malloc函数多一个参数,不需要人工计算空间大小. 例如malloc realloc calloc,如果他想申请20个int类型的空间,他将int * p =(int *)calloc(20malloc realloc calloc,sizeof(int)),这样可以节省人类的空虚

麻烦的计算. 但这不是它们之间最重要的区别. 应用后malloc的空间值是随机的,尚未初始化,但是calloc在应用后将空间一一初始化并将其值设置为0;

下面

int * p =(int *)malloc(20 * sizeof(int)); int * pp =(int *)calloc(20,sizeof(int));英蒂printf(“ malloc应用的空间值: \ n \ n”); for(i = 0; i <20; i ++){printf(“%d”,* p ++);} printf(“ \ n \ n”); printf(“ calloc值: \ n \ n”); for(i = 0; i <20; i ++){printf(“%d”,* pp ++);} printf(“ \ n”);

结果是

malloc realloc calloc_calloc malloc_calloc函数与malloc

许会问: 既然calloc不需要计算空间,并且可以直接初始化内存以避免错误,为什么不直接使用calloc函数,malloc的用途是什么?

实际上,一切都有两个方面. 有好的方面,也必有缺点. 这就是效率. 由于calloc函数需要为每个空间初始化值,因此它必须比malloc效率低,并且在现实世界中,空间应用程序在许多情况下不需要初始值,这就是为什么许多初学者会更多地接触malloc函数的原因. 原因.

在讨论了malloc和calloc之后,让我们讨论一下realloc函数.

realloc函数本质上与上面两个不同,

原型voidrealloc(void * ptr,size_tnew_Size)用于扩展动态内存(并且应用的动态空间不足,需要空间扩展操作)

ptr是指向原始空间基址的指针,而new_size是接下来需要扩展的大小.

intmain(void)(constintsize = 2000; int * p =(int *)malloc(20 * sizeof(int)); int * pp =(int *)realloc(p,size * sizeof(int)); printf(“原始的p_Address: %x扩展的pp_Address: %x \ n \ n”,p,pp); return0;}

结果是:

从图中可以看出,扩展后的地址与原始地址不同,但这仅取决于扩展后的内存大小.

实际上:

如果大小很小,并且原始动态内存后面有可用内存,则系统将直接在原始内存空间后面扩展容量,并返回原始动态空间基址;

如果大小很大,并且原始请求的空间后面没有足够的空间,则系统将重新应用一块(20 + size)* sizeof(int)内存,并复制原始空间的内容. 原始空间是免费的. ;

如果大小很大,则系统内存应用程序将失败,并返回NULL. 原始内存不会释放.

注意: 如果扩展的存储空间小于原始空间,则会发生数据丢失. 如果直接重新分配(p,0);相当于免费(p)

=============================================== ==== =======

这三个函数的声明是:

void *重新分配(void * ptr,未签名的newsize);

void * malloc(无符号大小);

void * calloc(size_t numElements,size_t sizeOfElement);

全部在stdlib.h函数库中

它们的返回值是请求系统分配的地址. 如果请求失败,则返回NULL.

malloc用于申请新地址,参数大小为所需内存空间的长度,例如:

char * p;

malloc realloc calloc_calloc函数与malloc_calloc malloc

p =(char *)malloc(20);

calloc与malloc相似,参数sizeOfElement是应用程序地址的单位元素的长度,而numElements是元素的数量,例如:

char * p;

p =(char *)calloc(20,sizeof(char));

此示例与上一个示例具有相同的作用

realloc是将空间重新分配给已经分配了地址的指针,参数ptr是原始空间地址,而newsize是重新应用的地址长度

例如:

char * p;

p =(char *)malloc(sizeof(char)* 20);

p =(char *)重新分配(p,sizeof(char)* 40);

请注意,此处的空间长度以字节为单位.

C的标准内存分配功能: malloc,calloc,realloc,free等.

malloc和calloc的区别是1个块和n个块之间的区别:

malloc调用的格式为(类型*)malloc(大小): 在内存的动态存储区域中分配一个长度为“ size”的连续区域,并返回该区域的第一个地址.

calloc调用形式为(type *)calloc(n,size): 在内存的动态存储区域中分配n个“大小”字节的块,并返回第一个地址.

realloc调用的形式是(type *)realloc(* ptr,size): 将ptr内存大小增加到size.

的呼叫形式

free是免费的(void * ptr): 释放ptr指向的一块内存空间.

C ++中的新增/删除功能.

1,int * p1 =(int *)malloc(0)//好的,p1! = NULL

2,int * p2 =(int *)重新分配(p1,newsize * sizeof(int));

// newsize很小,并且重新分配操作成功,p2 == p1

// newsize很大,重新分配操作成功,p2! = p1 && p2! = NULL

// newsize很大,当重新分配操作失败时,p2 == NULL

3,int * p3 =(int *)重新分配(NULL,10 * sizeof(int)); //好的,p3! = NULL


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-150402-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 许文龙
        许文龙

        时以为只有万恶的旧社会才会多男找一个老婆

      • 姬兰
        姬兰

      • 徐彬彬
        徐彬彬

        说明美国不愿面对岛礁的12海里内是中国的了

      热点图片
      拼命载入中...