动态内存1讲(案例——求素数)

本文探讨了静态数组存在的问题,并详细介绍了C++中的动态内存管理,包括malloc、calloc、realloc的使用及内存释放。同时,提供了一个案例,通过动态内存分配求解1到n之间的素数。
摘要由CSDN通过智能技术生成

一、静态数组存在的问题:1.不能根据变量n动态申请内存 2.不能申请大块内存

int arr[10];//静态数组

动态内存可以很好地解决静态数组的问题。

二、动态内存概念(动态内存:在堆内申请,堆大小大于1.8G)

1、动态内存有什么用?

   1.1 可以根据变量n动态申请数组

2、怎么使用动态内存?

    2.1 malloc(90%)

       申请动态内存(从堆里),有可能失败,返回NULL(1.堆内空间不够 2.堆内空间足够,但连续空间不够)

#include <malloc.h>//#include <stdlib.h>//头文件

	//动态内存申请10个整型空间;
	int* p = (int*)malloc(10 * sizeof(int));
	//动态内存申请20个字符空间;
	char* p2 = (char*)malloc(20 * sizeof(char));
	//动态内存申请100个double空间;
	double* p3 = (double*)malloc(100 * sizeof(double));

    2.2 calloc(1%)

int* p = (int*)calloc(10, sizeof(int));

   等价于

int* p = (int*)malloc(10 * sizeof(int));
for (int i=0; i<10; i++)
	{
		p[i] = 0;
	}

   2.3 realloc(9%)

 2.3.1申请重新分配有两种情况:

  •     申请成功: 

       1.原先内存后面如果有足够的空闲空间,则直接续给你;

       2.原先内存后面空闲空间不足,重新在堆内存中找足够大的连续的内存,分配给你(这时只需将前面的空间有效值拷贝过去,然后将前面空间释放)

  •     申请失败:堆内连续内存不够。
int n = 10;
	int* p = (int*)malloc(10 * sizeof(int));

	int* p = (int*)realloc(p, n * sizeof(int) * 2);

在上面2.1 malloc的例子上扩容2倍

//在这个基础上都扩容两倍
	//动态申请int空间10个
	int *p = (int*)malloc(10 * sizeof(int));
	p = (int*)realloc(p, 10*sizeof(int)*2);

	//动态申请字符空间20个
	char *p2 = (char*)malloc(20 * sizeof(char));
	p2 = (char*)realloc(p2, 20*sizeof(char)*2);

	//动态申请double空间100个
	double *p3 = (double*)malloc(100*sizeof(double));
	p3 = (double*)realloc(p3, 100*sizeof(double)*2);

2.3.2 常见的扩容倍数:1.5倍较好

3、怎么释放动态内存?(防止内存泄露)

4、注意事项:

      4.1 malloc的时候,前面的强转和后面的sizeof内的类型不一致,sizeof里面没有*号

      4.2 calloc中两个参数不要写反

      4.3 realloc:

            第一个参数需要填写的是原先内存的开头地址;

            第二个参数需要的是重新开辟的总字节数,不是在原先内存的基础上扩充的字节数

三、案例:求1~n内的素数

1、定义一个函数,思想如下图所示:

       从2开始(素数是大于1的自然数,直接将0和1排除,令p[0]=p[1]=0),判断3~9模2是否等于0,等于0,将其排除(算法中令p[j]=0);

       从3开始继续上述流程...

       重复上述步骤,直至找到1~n中所有素数;

#include <stdio.h>//头文件
#include <assert.h>


void Func(int n)
{
	int *p=(int*)malloc(n * sizeof(int)); 
	//int的大小(4)x*y   x:申请空间大小  y:申请空间单个大小,这里注意用int类型的指针接收,右边就强转int*(其他数据类型也一致);
	assert(p != NULL);
	//断言,判断是否申请成功;
	for (int i=0;i<n;i++)
	{
		p[i] = 1;//申请的每个格子给定初始值为1;
	}
	p[0] = p[1] = 0;

	for (int i = 2; i < n; i++)//从第二个下标开始遍历;
	{
		for (int j = i + 1; j < n; j++)//j从i的后一位开始遍历;
		{
			if (p[j]!=0 && j % i == 0)//若j下标存储的值不等于0且i是j的因子,则不是素数,将该值赋值为0;
			{
				p[j] = 0;
			}
		}
	}
	for (int i = 0; i < n; i++)//从0号下标开始遍历,找到存储的值不为0的打印出来,即为素数;
	{
		if (p[i] != 0)
		{
			printf("%d ", i);
		}
	}
}

2、主函数:设n=100,求1~n中的素数

int main()
{
	Func(100);
	return 0;
}

结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值