动态内存分配
c之malloc
函数原型:
void* malloc(size_t size);
- 为用户申请size个字节大小的空间
- 成功返回地址,失败返回0
常见使用方式:
//第一种是错误的,原因是返回为void*,缺少指针的二元素之一:类型,所以编译器不认识
int* a = malloc(sizeof(int));
//以下几种都正确
int* a = (int*)malloc(sizeof(int));
int* a = (int*)malloc(4); //int占4个字节
int* a = (int*)malloc(sizeof(int)*10); //分配10个int空间
c之calloc
函数原型:
void* calloc(size_t count, size_t size);
- 为用户申请count*size个字节大小的空间
- 成功返回地址,失败返回0
- 分配成功后,每个区域值设置为0
常见使用方式:
int* a = (int*)calloc(sizeof(int),3);
c之realloc
函数原型:
void* realloc(void* _Block, size_t Size);
- 为已分配好的内存_Block重新分配Size个字节大小的内存
- 成功返回地址重分配后的首地址,失败返回0
常见使用之例程讲解:
int* pa = (int*)calloc(sizeof(int), 10);
pa[0] = 1; pa[1] = 2; pa[2] = 3;
int* pb = (int*)realloc(pa, 20);
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
结果:
总结: 我们发现确实是重分配,并且数据也已经正确,但是在这里我们需要注意的是重分配有可能是扩大也有可能是缩小;大了可能会溢出,小了可能会数据丢失。
扩充: 若缩小内存,则新分配内存首地址就是原首地址。若扩大至一定内存,则极有可能由于后部代码块不够用,而重新在另一处开辟一块需要的内存大小,并且将原数据拷贝纸新内存,这样新内存的首地址就发生变化了
c之free
函数原型:
void free(void* _Block);
- 仅释放_Block动态分配的内存
常用形式:
int* a = (int*)malloc(sizeof(int));
free(a);
总结:虽然释放了内存,但以上代码会造成悬挂指针的问题,如下:
int* a = (int*)malloc(sizeof(int));
free(a);
cout << a;
结果:
总结: 依然能打印地址,所以还需要将a = nullptr (c++11标准以及标准之后)
c++之new
使用形式:
1、数据类型 * 指针变量名 = new 数据类型;
例如:
int * pa = new int;
2、数据类型 * 指针变量名 = new 数据类型[数量];
例如:
int * pa = new int[5];
- 失败返回0
常用形式:
int* pa = new int{ 1 };
cout << *pa << endl;
int* pb = new int[3]{1,2,3};
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
结果:
总结: 分配时就可进行初始化值
c++之delete
使用形式:
1、delete 指针; //释放类似于int * pa = new int;开辟的内存
2、delete [] 指针;//释放类似于int * pa = new int[5];开辟的内存
示例:
//必须配套使用
int* pa = new int{ 1 };
delete pa; //一个就这个
int* pb = new int[3]{1,2,3};
delete [] pb; //多个就这个
内存拷贝常用之memcpy
函数原型:
void* memcpy(void* _Dst, void* _Src, size_t Size);
- _Dst为目的地址
- _Src为原地址
- Size 拷贝字节数
- 将以_Src首地址开始的Size个字节拷贝到首地址为_Dst的内存区域
范例代码:
int* pa = new int[3]{ 1,2,3 };
int* pb = new int[3];
memcpy(pb, pa, sizeof(int)*3);
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
结果:
内存拷贝常用之memset
函数原型:
void* memset(void* _Dst, int val, size_t Size);
- 设置以首地址为_Dst开始的Size个字节内设置为val
- val最好是小于一个字节,否则截断一个字节的内容
范例代码:
int* pa = new int[3]{};
memset(pa, 0, sizeof(int) * 3); //这种基本上是最常用的
cout << pa[0] << " " << pa[1] << " " << pa[2] << endl;
//演示value高于一个字节用
memset(pa, 0xff32, sizeof(int) * 3); //纯属是演示用,平时不会这么用
cout << hex; //设置为16进制输出流
cout << pa[0] << " " << pa[1] << " " << pa[2] << endl;
结果:
感谢自己努力的学习!!认为还不错的大哥们记得点个赞哦!谢谢0.0