当前位置: 首页 > article >正文

4. 指针和动态内存

一、栈vs堆

stack、static/global、Code在编译期大小就确定了。只有堆区(动态分配内存),它不是固定的

🍐栈溢出:无穷递归的情况

  • 内存中预留给栈的空间,在运行期间不会增长。
  • 堆是一块很大,可以自由使用的内存

🍊 堆主要涉及的function

🍋 例子

  • 在堆上分配的内存需要手动释放

二、malloc calloc realloc free

🍌 malloc

不能对void* 直接进行操作,为了使用这块内存,需要对指针进行类型转换 

🍉 calloc

  • 与 malloc 不同,有两个传输参数,第一个参数是特定类型的元素数量,第二个参数是类型的大小
  • malloc分配完内存之后并不会对其进行初始化,calloc会将其初始化为0

🍇 relloc

  • 如果有一块动态分配的内存,然后你想修改内存的大小
  • 第一个参数是指向已经分配内存的起始地址的指针,第二个参数是新的内存块的大小

🍓  free

🍈例子

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int n;
	printf("请输入数组大小\n");
	scanf("%d",&n);
 
	int *A = (int*)calloc(n,sizeof(int));
	int *B = (int*)malloc(n*sizeof(int));	//实测也初始化后居然是0
 
 
	for(int i=0;i<n;i++)
		printf("%d ",A[i]);
	printf("\n");
 
	for(int i=0;i<n;i++)
		printf("%d ",B[i]);
	printf("\n");
 
	free(A);
	free(B);
 
	A[2] = 8;	// 我的开发环境free后仍可以修改
 
	printf("after free\n");
	for(int i=0;i<n;i++)
		printf("%d ",A[i]);
	printf("\n");
 
	for(int i=0;i<n;i++)
		printf("%d ",B[i]);
	printf("\n");
 
 
	int *c = (int*)malloc(n*sizeof(int));
	int *d = (int*)realloc(c,2*n*sizeof(int));
	printf("旧地址:%d ,新地址:%d \n",c,d);
}

输出

请输入数组大小
10
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
after free
0 0 8 21845 0 0 0 0 0 0 
1433758336 21845 1433755664 21845 0 0 0 0 0 0 
旧地址:1433758384 ,新地址:1433758384 

三、内存泄漏

/*
	简单的赌博游戏
	JQK电脑自动洗牌
	玩家猜测Q的位置  1 2 3
	猜对了:收获3倍下注金额
	猜错了:失去下注金额
	开局有100块
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int cash = 100;
 
void play(int bet)
{
	//char c[3] = {'J','Q','K'};	// 正常写法,不会有内存泄露【因为栈自动“free”】
	char *c = (char*)malloc(1024*1024*sizeof(char));
	c[0] = 'J';	c[1] = 'Q';	c[2] = 'K';
 
	printf("洗牌中\n");
	srand(time(NULL));	// 随机数种子
	int i;
	for(i=0;i<5;i++)
	{
		int x = rand()%3;
		int y = rand()%3;
		int temp = c[x];
		c[x] = c[y];
		c[y] = temp;		// 调换xy位置
	}
 
	int playersGuess;
	printf("Q 在哪个位置  1,2,3?\n");
	scanf("%d",&playersGuess);
 
	if(c[playersGuess-1] == 'Q')
	{
		cash += 3*bet;
		printf("你赢了,结果是 \"%c %c %c\" 总金额 = %d\n",c[0],c[1],c[2],cash);
	}
	else
	{
		cash -= bet;
		printf("你输了,结果是 \"%c %c %c\" 总金额 = %d\n",c[0],c[1],c[2],cash);
	}
 
	//free(c);
}
 
 
int main()
{
	int bet;
	printf("总金额 = %d\n",cash);
	while(cash>0)
	{
		printf("请输入下注金额");
		scanf("%d",&bet);
		if(bet==0||bet>cash) break;
		play(bet);
		printf("\n*************************\n");
	}
}


http://www.kler.cn/a/457587.html

相关文章:

  • 滴滴数据分析80道面试题及参考答案
  • Redis面试相关
  • 《Xsens动捕与人形机器人训练》讲座将于1月9日下午2:30在线上召开
  • 家政上门小程序如何创建?家政服务怎么能少了小程序帮手
  • 【PCIe 总线及设备入门学习专栏 4.5 -- PCIe Message and PCIe MSI】
  • LinuxC高级day5
  • Pytorch | 利用PC-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
  • 【13】Selenium+Python UI自动化测试 集成日志(某积载系统实例-07)
  • 【学习笔记】ChatGPT原理与应用开发——基础科普
  • No.29 笔记 | CTF 学习干货
  • C++ 设计模式:策略模式(Strategy Pattern)
  • 「Mac畅玩鸿蒙与硬件48」UI互动应用篇25 - 简易购物车功能实现
  • 【Spring】基于注解的Spring容器配置——@Scope注解
  • 如何通过采购管理系统提升供应链协同效率?
  • Android Bluetooth 问题:BluetoothAdapter enable 方法失效
  • 【2025最新计算机毕业设计】基于SpringBoot的网上服装商城系统(高质量项目,可定制)【提供源码+答辩PPT+文档+项目部署】
  • 一起来看--红黑树
  • TVS二极管选型【EMC】
  • 从0入门自主空中机器人-2-2【无人机硬件选型-PX4篇】
  • 每日一题 354. 俄罗斯套娃信封问题
  • 2025年阿斯利康GATE笔试测评春招校招社招笔试入职测评行测题型解读揭秘
  • MATLAB 车牌自动识别系统设计 SVM支持向量机方法 车牌识别
  • 代码随想录第60天
  • python opencv的sift特征检测(Scale-Invariant Feature Transform)
  • 嵌入式系统 第十二讲 块设备和驱动程序设计
  • 跟着问题学18——大模型基础transformer模型详解(4)解码器