动态内存申请

动态内存申请

  • 断言
//一般与下面的内存申请配套使用
#include<assert.h>  //所需要的头文件
int p=NULL;
assert(p);   //p等于 触发断点,中断程序 断言
//类似于
//if(p=NULL)return ;
  • malloc
#include <malloc.h>  //所需头文件
//也可用 #include <stdlib.h>

//该申请方式申请的动态内存,不做初始化
//原型:void*  malloc(size_t _Size);  //size:申请内存的总字节数

  • calloc
#include <malloc.h>  //所需头文件
//也可用 #include <stdlib.h>

//该申请方式申请的动态内存,会初始化为零
//原型:void*  calloc( size_t _Count,size_t _Size); //count:申请的数据个数,size:每个数据占用的字节数


  • realloc
#include <malloc.h>  //所需头文件
//也可用 #include <stdlib.h>

//内存重新申请,保留原数据
//void*  realloc(void*  _Block,size_t _Size); // _Block:原指针,_Size:重新申请的内存大小
  • 释放内存
//与上面内存申请配套使用
void  free(void* _Block);  //_Block:原指针

//什么时候释放,当你不需要它的时候释放
//注意点: 从哪里申请的一定要从哪里释放,即当你的指针做了偏移,一定要偏移回去再释放
//如果没有释放内存,直到整个程序关掉,内存才会被操作系统回收释放
//优点:节约内存

malloc的使用

#include<stdio.h>
#include<malloc.h>
int main()
{
	int* p=NULL;
	//一级指针动态申请内存成为一维数组
	p=(int*)malloc(sizeof(int)*3);
	assert(p);
	//(指针类型)malloc(sizeof(指针所指向的类型)*个数);
	//当申请一个变量内存时,可以不用写 *个数
	//int* p 
	//指针的类型: 去掉变量名: int*
	//指针所指向类型: 去掉变量名和* :int (操作的数据类型)
	for (int i = 0; i < 3; i++) 
	{
		p[i] = i;
		printf("%d\t", p[i]);
	}
	printf("\n");
	return 0;
}

calloc和realloc的使用

#include<stdio.h>
#include<malloc.h>
int main()
{

	int* pc = (int*)calloc(3, sizeof(int));		//3也可以是变量
	assert(pc);
	for (int i = 0; i < 3; i++) 
	{
		printf("%d\t", pc[i]);
	}
	printf("\n");
	int* pr = realloc(pc, sizeof(int) * 6);	//其中sizeof(int) * 6一定要比原来大小要大
	assert(pr);
	for (int i = 0; i < 6; i++) 
	{
		printf("%d\n", pr[i]);
	}
	//free(pc);//同一段内存不能被重复释放
	//pc = NULL;
	free(pr);//因为申请后只有一段内存,所以只要对pr释放一次就行了
	pr = NULL;
	return 0;
}

经典错误

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
int main()
{
	int num = 0;
	scanf_s("%d", &num);
	//int array[num];  //错误 ,定义数组长度必须是常量,有些编译器可能不会报错
	int* array = (int*)malloc(sizeof(int) * num);  //理解为一个数组
	assert(array);
	array++;
	array--;//指针偏移后一定要还原再释放
	free(array);
	array = NULL;				//防止野指针
	return 0;
}
  • 如果指针偏移后没有还原就会出现异常中断
    在这里插入图片描述
    在这里插入图片描述 + 指针充当变量的两种途径
  1. 指向变量(存在于栈区)
	int a = 1;
	int* pa = &a;
	*pa = 1234;
	int result = (*pa) * 3;
  1. 动态内存申请(存在于堆区)
	//申请一个变量内存
	int* pM = NULL;
	pM = (int*)malloc(sizeof(int));
	assert(pM);
	*pM = 1003;
	free(pM);

二维数组的申请

  • 二级指针申请
	//二级指针
	int** pArray = NULL;
	pArray = (int**)malloc(sizeof(int*) * 4);  
	//p[0] p[1]  p[2]  p[3] 
	assert(pArray);
	for (int i = 0; i < 4; i++) 
	{
		pArray[i] = (int*)malloc(sizeof(int) * 3);
		//p[i][0] p[i][1]  p[i][2]  p[i][3] 
		assert(pArray[i]);
	}
	for (int i = 0; i < 4; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			pArray[i][j] = i * j;
			printf("%d\t", pArray[i][j]);
		}
		printf("\n");
	}
  • 二级指针的释放
	//释放顺序和申请顺序相反的
	for (int i = 0; i < 3; i++) 
	{
		free(pArray[i]);
	}
	free(pArray);
  • 数组指针申请二维数组
	int(*p2D)[4] = NULL;
	//(指针类型)malloc(sizeof(指针所指向的类型)*个数);
	p2D = (int(*)[4])malloc(sizeof(int[4]) * 3);
	assert(p2D);
	for (int i = 0; i < 3; i++) 
	{
		for (int j = 0; j < 4; j++) 
		{
			p2D[i][j] = i * j;
			printf("%d\t", p2D[i][j]);
		}
		printf("\n");
	}
	free(p2D);
	p2D = NULL;
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值