malloc、calloc以及realloc的区别与联系
- malloc
malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
由于malloc的返回值是void*,所以需要我们手动的去强制类型转换成为我们想要的类型。
需要和free配对使用。
- 原型
extern void *malloc(unsigned int num_bytes);
- 头文件
#include<stdlib.h>//或者
#include<malloc.h>
- 函数声明
void *malloc(size_t size);
备注:void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型)。
- 返回值
如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
- 说明
关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。它能向系统申请分配一个长度为num_bytes(或size)个字节的内存块。
一般它需和free函数配对使用。free函数能释放某个动态分配的地址,表明不再使用这块动态分配的内存了,实现把之前动态申请的内存返还给系统。
- calloc
在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
- 头文件
#include<stdlib.h>
#include<malloc.h>
- 函数声明
void *calloc(size_t n, size_t size);
- 返回值
如果分配成功则返回指向被分配内存的指针,会初始化内存数据为0,否则返回空指针NULL。
- realloc
reset allocation。先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
- 原型
extern void *realloc(void *mem_address, unsigned int newsize);
- 头文件
#include<stdlib.h>//或者
#include<malloc.h>
- 函数声明
void *realloc(void* block, size_t size);
- 内存分配
- 如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。
- 如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>//stdlib.h里面定义了五种类型、一些宏和通用工具函数。
类型例如size_t、wchar_t、div_t、ldiv_t和lldiv_t;
宏例如EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等等;
常用的函数如malloc()、calloc()、realloc()、free()、system()、
atoi()、atol()、rand()、srand()、exit()等等。
int main() {
int* p1 = (int*)malloc(sizeof(int));
free(p1);
int* p2 = (int*)calloc(10, sizeof(int));
int* p3 = (int*)realloc(p2, 10 * sizeof(int));
//free(p2);//不需要free,系统会在扩大了p2的内存后自动释放p2
free(p3);
return 0;
}
函数名 | 特点 |
malloc | 只负责开辟空间 |
calloc | 开辟空间,会进行初始化。 |
realloc | 1.在第一个参数为空指针时,相当于malloc。 2.对传入的指针所指向的内存块进行扩容(两种方式,见下图)。 |