c++之动态内存分配篇

动态内存分配

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

发布了9 篇原创文章 · 获赞 11 · 访问量 878

猜你喜欢

转载自blog.csdn.net/u010092716/article/details/104329872