C语言基础知识(7): 动态内存分配(malloc)


注:转载请标明原文出处链接:https://xiongyiming.blog.csdn.net/article/details/105519162


1 传统数组的缺点

  1. 数组的长度必须事先指定,并且只能是常整数,不能是变量;
    例如:int a[5]; //正确
               int len =5; int a[len]; //错误

  2. 传统形式定义的数组,该数组的内存无法手动释放;
    例如:在一个函数运行期间,系统为该函数中数组所分配的空间一直存在,知道该函数运行结束,数组占用的空间才会被系统释放。

  3. 数组的长度不能在程序运行的过程中动态变化;

  4. 传统方式定义的数组不能跨函数使用;
    例如:A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行结束后,A函数中的数组将无法被其他函数使用。




2 为什么要动态分配内存

动态数组很好的解决了传统数组的缺陷;
传统数组也称之为静态数组



3 动态数组的构造

3.1 malloc函数的使用

malloc 是 memory allocate 的缩写


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

int main()
{
	
	int i = 5;//静态分配  分配了4个字节
	int *p = (int *)malloc(4); //动态分配 分配了4+4=8个字节 p变量占4个字节(静态分配),
	                          //p指向的内存占用了4个字节(动态分配)

	/*
	1 使用malloc函数,必须包含malloc.h头文件;
	2 malloc函数只有一个形参,并且形参是整型;
	3 malloc(4)表示请求系统为本程序分配4个字节;
	4 malloc函数分配内存并只能返回第一个字节的地址,
	     需要用(int *)进行强制类型转换;
	5 p本身所占用的内存是静态分配的,p指向的内存是动态分配的
	*/
		
	free(p);//表示把p指向的内存释放掉(动态分配的内存被释放掉)
	       //p本身的内存是静态的,只能由p所在的函数终止时又系统自动释放





	system("pause");
	return 0;
	

}

说明:

  1. 使用malloc函数,必须包含malloc.h头文件;

  2. malloc函数只有一个形参,并且形参是整型;

  3. malloc(4)表示请求系统为本程序分配4个字节;

  4. malloc函数分配内存并只能返回第一个字节的地址,需要用 (int ∗) 进行强制类型转换;

  5. p本身所占用的内存是静态分配的,p指向的内存是动态分配的;



通过函数对动态分配内存的值进行修改

在这里插入图片描述


由上图可知,指针变量 p 为 int ∗ 类型并且是静态内存,p指向动态分配内存的第一个字节的地址。


代码示例

#pragma warning( disable : 4996)
#include<stdio.h>
#include<iostream>
#include<malloc.h>


//使用f函数修改*p的值//
int f(int * q)
{
	*q = 200;
	
	return 0;

}


int main()
{
	
	int i = 5;//静态分配  分配了4个字节
	int *p = (int *)malloc(sizeof(int)); //sizeof(int)返回值是int 所占的字节数
	*p = 10;

	printf("*p=%d\n", *p);

	f(p);  //p是 int * 类型

	printf("*p=%d\n", *p);//*p的值被修改
	
	free(p);


	system("pause");
	return 0;
	

}

运行结果

在这里插入图片描述



3.2 动态一维数组的构造


在这里插入图片描述



代码示例

#pragma warning( disable : 4996)
#include<stdio.h>
#include<iostream>
#include<malloc.h>


//使用f函数修改*p的值//
int f(int * q)
{
	*q = 200;
	
	return 0;

}


int main()
{
	
	int a[5]; //静态数组 共占用20个字节

	int len;
	int * pArr;

	printf("请输入数组需要存放的元素个数:\n");
	scanf("%d", &len);
	pArr = (int *)malloc(4 * len);//动态分配 动态数组
	                        //可近似理解为 int pArr[len];

	printf("请依次输入%d个元素:\n",len);

	//一维数组输入
	for (int i = 0; i < len; i++)
	{
		scanf("%d", &pArr[i]); //或使用 &(*(pArr+j))
	}


	printf("输入数组的元素依次为:\n");
	//一维数组输出 方式1 *(pArr+j)
	for (int j = 0; j < len; j++)
	{
		printf("%d\n", *(pArr+j));
	}

	printf("-------------------\n");

	//一维数组输出 方式2 pArr[j]
	for (int j = 0; j < len; j++)
	{
		printf("%d\n", pArr[j]);
	}

	free(pArr);


	system("pause");
	return 0;
	

}

运行结果

在这里插入图片描述




4 静态内存和动态内存的比较

  1. 静态内存是系统自动分配,由系统自动释放;
    动态内存是手动分配,手动释放;

  2. 静态内存是在分配的,动态内存是在分配的;




5 跨函数使用内存的问题


(1) 静态内存不可以跨函数使用


#pragma warning( disable : 4996)
#include<stdio.h>
#include<iostream>
#include<malloc.h>



int f(int ** q) //q是指针变量,无论q是什么类型的指针变量是哪个,q只占4个字节
{
	int i = 100;
	//*q等价于p//
	*q = &i; 
	
	
	return 0;

}


int main()
{
	int a = 5;
	int * p;
	p = &a;
	printf("*p=%d\n", *p);

	f(&p);
	printf("*p=%d\n", *p);

	system("pause");
	return 0;
	

}

运行结果

在这里插入图片描述

说明:对于上面程序中的f函数执行完毕后会自动释放,因此不能跨函数使用。



使用动态内存可以跨函数使用


#pragma warning( disable : 4996)
#include<stdio.h>
#include<iostream>
#include<malloc.h>



int f(int ** q) //q是指针变量,无论q是什么类型的指针变量是哪个,q只占4个字节
{
	*q = (int *)malloc(sizeof(int)); //动态分配
	           //等价于p= (int *)malloc(sizeof(int));
	
	**q = 100;

	return 0;

}


int main()
{
	int a = 5;
	int * p;
	p = &a;
	printf("*p=%d\n", *p);

	f(&p);
	
	printf("*p=%d\n", *p);

	system("pause");
	return 0;
	

}

运行结果

在这里插入图片描述

发布了187 篇原创文章 · 获赞 2039 · 访问量 97万+

猜你喜欢

转载自blog.csdn.net/zaishuiyifangxym/article/details/105519162