c语言内存

在这里插入图片描述

1.c语言动态内存管理

1.1为什么存在动态内存管理

常见的开辟内存方式有:

int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间

上诉的开辟空间的方式有两个特点:
1.空间开辟大小是固定的。
2.数组在声明的时候,必须指定数组长度,它所需要的内存在编译时分配

1.2动态内存函数的介绍

malloc 作用:申请空间(连续)
calloc 作用:申请空间+数据初始化
realloc 作用:修改空间大小
free    作用:释放空间

示例:

#include <stdio.h>
#include <stdlib.h>

/*
		malloc 作用:申请空间(连续) 效率高 *掌握
		calloc 作用:申请空间 + 数据初始化 了解
		realloc 作用:修改空间大小
		free    作用:释放空间
		*/

int main()
{
	//1.利用malloc函数申请一片连续的空间
	//需求:申请一片空间,要存储100个int类型的整数
	//返回这边空间的首地址
	int *p = malloc(100 * sizeof(int));
	//int* p = calloc(100, sizeof(int));
	printf("%p\n", p);

	// 2.赋值
	for (int i = 0; i < 100; i++)
	{
		//第一种赋值方式
		*(p + i) = (i + 1) * 10;
		//第二种赋值
		//p[i] = (i + 1) * 10;
	}

	

	// 4.扩容,20int类型的整型
	int *pp = realloc(p, 20 * sizeof(int));

	//3.遍历
	for (int i = 0; i < 120; i++)
	{
		printf("%d\n", *(p + i));
	}

	// 5.释放空间
	//如果申请的空间不需要再进行使用了,那么记得一定要释放
	free(pp);

	return 0;
}

1.3常见的函数细节点

#include <stdio.h>
#include <stdlib.h>


/*
	malloc 申请空间(连续)  掌握
	free   释放空间        

	calloc 申请空间+数据初始化  了解
	realloc 修改空间大小       

	1.malloc 创建空间的单位是字节
	2.malloc 返回的是void类型的指针,没有步长的概念,也无法获取空间中的数据,需要强转
	3.malloc 返回的仅仅是首地址,没有总大小,最好定义一个变量记录总大小
	4.malloc 申请的空间过多,会产生虚拟内存
	5.malloc 申请的空间不会自动消失,如果不能正确释放,会导致内存泄漏
	6.malloc 申请的空间没有初始化值,需要先赋值才能使用
	7.free 释放完空间之后,空间中数据叫做脏数据,可能被清空,可能被修改为其他值

	8.calloc就是在malloc的基础上多一个初始化的动作
	9.realloc 修改之后的空间,地址值有可能发生变化,也有可能不会改变,但是原本的数据不会丢失
	10.realloc 修改之后,无需释放原来的空间,函数底层会进行处理

*/
	

int main5()
{
	// void*通用性 可以转换成其他类型也可以
	// int* :指针的步长
	// p:首地址
	int* p = malloc(25 * sizeof(int));//100字节 // 25 int 50 short 100 char 
	int size = 25;



	return 0;
}
#include <stdio.h>
#include <stdlib.h>

int main6()
{
	// 5.申请内存空间过多,会产生虚拟内存
	//虚拟内存:
	//	虚拟:假的
	//  当申请的空间过多,因为每一个内存空间不会在刚申请的时候立马使用
	//  所以c语言并不会立马就在内存中去开辟空间,而是什么时候存数据了,才会真正的分配内存空间
	// 目的:为了提高内存的使用效率

	// 表示单词申请空间的字节大小(1G)
	int number = 1024 * 1024 * 1024;

	//利用循环不断第申请空间
	// malloc 申请空间(连续) 掌握
	//如果申请空间成功,返回这个空间的首地址
	//如果申请失败,则返回NULL
	
	int count = 0;

	while (1)
	{
		int* p = malloc(number);
		count++;

		if (p == NULL)
		{
			printf("申请空间失败");
			break;
		}
		printf("内存%d申请成功%p\n", count, p);
	}


	return 0;
}
#include <stdio.h>
#include <stdlib.h>

int main7()
{
	
	//7.释放完空间之后,空间的数据叫做脏数据,可能被清空,可能被修改为其他值
	//8.calloc就是在malloc的基础上多一个初始化的动作

	//1.申请一片连续的空间存储10个int类型的整数
	int* p = malloc(10 * sizeof(int));
	int size = 10;

	//2.给这片空间赋值
	for (int i = 0; i < size; i++)
	{
		*(p + i) = (i + 1) * 10;
	}

	//3.遍历
	printf("遍历空间中的数据为:\n");
	for (int i = 0; i < size; i++)
	{
		printf("%d ", *(p + i));
	}
	printf("\n");
	//4.释放空间
	free(p);
	//5.释放之后再次遍历
	printf("释放之后遍历数据为:\n");
	for (int i = 0; i < size; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
}
#include <stdio.h>
#include <stdlib.h>

int main()
{
	/*
		malloc 申请空间(连续)
		free   释放空间

		calloc 申请空间+数据初始化 
		realloc 修改空间大小(扩容)

		9.realloc修改之后的空间,地址值由可能发生变化,也有可能不会改变,但是原本的数据不会丢失
			如果内存中已经无法申请空间了,会返回NULL
		10.realloc 修改之后,无需释放原来的空间,函数底层会进行处理
	*/

	//1.申请一片连续的空间存储10个int类型的整数
	int* p = malloc(10 * sizeof(int));
	int size = 10;
	printf("修改之前的内存地址为:%p\n", p);

	//2.给这片空间赋值
	for (int i = 0; i < size; i++)
	{
		*(p + i) = (i + 1) * 10;
	}

	// 3.修改大小
	//realloc修改之后,无需释放原来的空间,函数底层会进行处理
	//如果内存地址没变,底层在原来空间的后面接着申请的
	//如果内存地址变了,申请一个新的大的空间,把原来的数据拷贝到新的空间当中,再把原来的空间给free掉
	int* p2 = realloc(p, 20 * sizeof(int));
	int size2 = 20;
	printf("修改之后的内存地址为:%p\n", p2);

	//3.遍历
	printf("遍历空间的数据为:\n");
	for (int i = 0; i < size2; i++)
	{
		printf("%d ", *(p2 + i));
	}
	printf("\n");
	free(p2);
	return 0;
}

1.4c语言的内存结构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

c语言中堆和栈的区别
1.存储位置:
栈:栈是自动分配的内存区域,通常位于进程的高地址处,它用于存储局部变量和函数调用时的参数和返回地址。
堆:堆是动态分配的内存区域,位于进程的低地址位,它通过调用malloc、calloc,realloc和free等函数来分配和释放内存

2.内存分配:
栈:内存分配自动的,由编译器自动管理。栈的内存分配和释放速度较快,但大小有限
堆:内存分配是动态的,需要程序员手动管理。堆的内存分配和释放速度较慢,但大小可以非常大

3.内存大小:
栈:每个线程都有自己的栈空间,大小通常较小,通常在几kb到几mb之间。
堆:所有线程共享堆空间,大小通常较大,受限于操作系统和硬件的限制。

4.内存管理:
栈:内存管理由操作系统自动完成,程序员不需要手动释放
堆:内存管理需要自己手动完成,程序员需要调用free函数来释放内存,否则会造成内存泄漏

5.访问方式:
栈:数据访问是连续的,通常通过局部变量和函数参数访问。
堆:数据访问可以通过指针进行,灵活性更高
存分配是动态的,需要程序员手动管理。堆的内存分配和释放速度较慢,但大小可以非常大

3.内存大小:
栈:每个线程都有自己的栈空间,大小通常较小,通常在几kb到几mb之间。
堆:所有线程共享堆空间,大小通常较大,受限于操作系统和硬件的限制。

4.内存管理:
栈:内存管理由操作系统自动完成,程序员不需要手动释放
堆:内存管理需要自己手动完成,程序员需要调用free函数来释放内存,否则会造成内存泄漏

5.访问方式:
栈:数据访问是连续的,通常通过局部变量和函数参数访问。
堆:数据访问可以通过指针进行,灵活性更高

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值