005-Cpp 动态内存分配函数
文章目录
Cpp 动态内存分配函数
1: cpp 动态内存分配
void* malloc(unsigned int size);
void* realloc(void *ptr, unsigned int newsize);
void* calloc(size_t numElements, size_t sizeOfElement);
加上一种new关键字,这四个都可以用来向内存申请空间
2: malloc
malloc(unsigned int size)
,它可以在内存的堆(Heap)区域申请连续大小为 size 个字节的空间,然后成功的话返回void*
指针(C/C++中,void*
可以被强制转换为其他类型的指针,像int*
等等),这个指针是申请这段连续空间的首地址,如果申请失败的话就返回 NULL 指针。
3: calloc
calloc(unsigned int n, unsigned int size)
,它可以在内存的堆(Heap)区域申请连续 n 个空间,每个空间包含了 size 个字节的大小,也就是总共向内存申请了 n*size 个字节的空间大小,然后成功的话返回void*
指针(这列的也是可以被强制转换的),这个指针是申请这段连续空间的首地址,如果申请失败的话就返回 NULL 指针。
4: realloc
realloc(void *ptr, unsigned int newsize)
,这个的作用是向内存申请一个 newsize 的空间大小。当使用 malloc 申请的内存不够用的时候,就是用 realloc 来进行申请更大的空间,前面的指针 ptr 就是一开始用 malloc 申请所返回的指针。realloc 申请的方式是从内存堆的开始地址高地址查找一块区域,这块区域大于 newsize 的大小,申请成功后将原本的数据从开始到结束一起拷贝到新分配的内存区域,然后将原本 malloc 申请的区域释放掉(注意的是:原来的指针是自动释放的,不需要使用 free 来进行释放)。最后再这块区域的首地址返回。当内存不再使用时,要记得用 free()函数进行释放。
5: new
new
是 C++提供的关键字,也是操作符,我们可以使用 new 在内存的堆上创建一个对象,在创建对象的时候,new 其实做了以下的操作:在堆上获得一块内存空间->调用构造函数(创建建档的类型变量时除外)->返回正确的指针;char* p = new char(‘e’):分配1个char类型大小的内存空间;
char* p = new char[5]: 分配5个char类型大小的内存空间
6: demo.cpp
|
|
7: 总结与比较
函数 | 申请区域 | 申请长度 | 是否初始化 | 头文件 |
---|---|---|---|---|
malloc | heap | size | void* | <stdlib.h>/<malloc.h> |
calloc | heap | n * size | void* | <stdlib.h>/<malloc.h> |
realloc | heap | newsize | void* |
- 如果申请调用成功,malloc()和 calloc()函数都会返回所分配的内存空间的首地址;
- free()释放函数时紧跟着 malloc、calloc、realloc,因为它们都是返回 void*;而 new 使用的时 delete;
- malloc 和 calloc 之间的区别就是:malloc 申请成功后没有初始化,这样会导致一些垃圾数据的存在,calloc 会初始化,将申请到的这一段连续空间初始化为 0,如果是实型数据的话,则会初始化为浮点数的 0;
- malloc、calloc、realloc 三者都是返回 void*,C/C++支持强制转换 void*成其他类型的指针;
- malloc 是在动态存储区域申请分配一块长度为 size 字节的连续区域,并返回这块区域的首地址;calloc 是在动态存储区域申请分配 n 块长度为 size 字节的区域,并返回这块区域的首地址;realloc 是将 ptr 内存大小增大到 newsize 个字节;
- realloc 是从堆上分配内存,在扩大空间的时候会直接在现存的数据后面获得附加的字节,如果空间能够满足的话就扩展,如果不满足的话,那就从堆的开始地址开始寻找,找到第一个足够大的自由块,然后将现有的数据拷贝到新的位置,而老的那一块还是放到堆上。
文章作者 lucas
上次更新 2023-04-11 (83ac18e)