动态内存分配

本文详细介绍了传统数组的局限性,如长度固定、无法跨函数使用等,并阐述了动态内存分配如何解决这些问题。通过malloc函数,可以动态创建数组并自由调整大小,同时讲解了动态内存分配的释放方法。此外,还讨论了静态内存和动态内存的区别,以及如何通过多级指针实现跨函数使用内存。最后,通过示例代码展示了动态一维数组的构造和管理。
摘要由CSDN通过智能技术生成

一.传统数组(静态数组)的缺点

1.数组长度必须事先制定,且只能是长整数,不能是变量。

int a[5]  //ok

int len=5; int a[len];  //error

2.数组一旦定义,系统为该数组分配的内存空间会一直存在,无法手动释放,除非该数组所在的函数终止,由系统自动释放。

3.数组的长度一旦定义无法再改变

4.传统方式定义的数组不能跨函数使用。A函数定义的数组在A函数运行期间可以被其他函数使用,但A函数终止后,则无法再被其他函数使用。

二.动态内存分配

动态数组很好地解决了传统数组的缺陷。

  1. malloc是memory(内存)和allocate(分配)的缩写
  2. 使用malloc函数,必须添加malloc.h头文件
  3. malloc函数只有一个形参,并且形参是整型
  4. malloc(x) x表示请求系统为本程序分配x个字节
  5. malloc函数只能返回第一个字节的地址

int *p=(int *)malloc(200);      200/4=50个int 类型的变量

char *p=(char *)malloc(200);      200/1=200个char 类型的变量

double *p=(double *)malloc(200);      200/8=25个double 类型的变量

(int *)malloc(100)      (int *)表示强制类型转换,将返回的第一个字节的地址转换为想要的类型

p变量占4个字节,p所指向的内存占200个字节;

p本身所占的内存是静态的,p所指向的内存是动态的

free(p)  //把p指向的内存给释放掉,p本身所占的内存是静态的,无法手动释放

#include <stdio.h>
#include <malloc.h>

void f(int *q) {
	// *p=200;  //error  p不能跨函数使用
	// q=200;   //error
	// **q=200  //error只有指针变量前面可以加*,*q是整型变量,不能在其前面加*
	*q = 200;
	//free(q);  
	//把q所指向的内存释放掉,在本程序中q和p指向同样的四个字节,
    //释放掉后不能再输出*p(即p指向的内存)
}

int main(void) {
	int *p = (int *)malloc(sizeof(int));
	//sizeod(int)返回值是int所占的字节数,为4,
	//p存放这四个字节的地址(即第一个字节的地址),*p代表这四个字节
	*p = 10; //把10赋值给以p的内容为地址的变量,即sizeof(int)占的内存

	printf("%d\n", *p); //10
	f(p); //p是int*类型
	printf("%d\n", *p);  //200   第20行
	return 0;
}

三.动态一维数组构造

构造方法:

int len;

int *pArr;

pArr=(int *)malloc(sizeof(int)*len);  //构造动态数组,类似于int pArr[len]

例子:

#include <stdio.h>
#include <malloc.h>

int main(void) {
	int a[5];//int类型变量占4个字节,故数组包含20个字节,每4个字节被当做一个int变量
	int len;
	int *pArr;//前四个字节对应的元素,即数组pArr的第一个元素
	int i;

	//动态构造一维数组
	printf("请输入数组长度:");
	scanf("%d", &len);
	pArr = (int *)malloc(4 * len); //类似于int pArr[len]
	//pArr是int类型的数组,数组长度由len决定

	//对一维数组进行操作   赋值

	for (i = 0; i < len; i++)
		scanf("%d", &pArr[i]);

	printf("一维数组的内容是:\n");
	for (i = 0; i < len; i++)
		printf("%d\n", pArr[i]);
	free(pArr);//释放掉动态分配的数组

	return 0;
}

四.静态内存和动态内存的比较

  • 静态内存是在栈分配的,由系统自动分配,由系统自动释放。
  • 动态内存是在堆分配的,由程序员手动分配,手动释放。

四.跨函数使用内存的问题

  • 多级指针

int i=0;

int *p=&i;

int **q=&p;

int ***r=&q;             i=***r

  • 静态内存不能跨函数使用
#include <stdio.h>
//#include <malloc.h>
void f(int **q) {
	int i = 5;
	//*q=i  //error *q=p 相当于p=i 错误
	*q = &i;
}

int main(void) {
	int *p;
	f(&p);  //p能够保存i的地址,但不能访问i的空间
	printf("%d\n", *p);//函数f执行完后,i所占的内存被释放
	return 0;
}
//输出 0
  • 动态内存可以跨函数使用
#include <stdio.h>
#include <malloc.h>

void f(int **q) {
	*q = (int *)malloc(sizeof(int));
	//*q相当于p   **q对*q
	**q = 5;
}

int main(void) {
	int *p;
	f(&p);  //
	printf("%d\n", *p);//
	return 0;
}
//输出 5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值