注:转载请标明原文出处链接:https://xiongyiming.blog.csdn.net/article/details/105519162
1 传统数组的缺点
-
数组的长度必须事先指定,并且只能是常整数,不能是变量;
例如:int a[5]; //正确
int len =5; int a[len]; //错误 -
传统形式定义的数组,该数组的内存无法手动释放;
例如:在一个函数运行期间,系统为该函数中数组所分配的空间一直存在,知道该函数运行结束,数组占用的空间才会被系统释放。 -
数组的长度不能在程序运行的过程中动态变化;
-
传统方式定义的数组不能跨函数使用;
例如: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;
}
说明:
-
使用malloc函数,必须包含malloc.h头文件;
-
malloc函数只有一个形参,并且形参是整型;
-
malloc(4)表示请求系统为本程序分配4个字节;
-
malloc函数分配内存并只能返回第一个字节的地址,需要用 (int ∗) 进行强制类型转换;
-
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 静态内存和动态内存的比较
-
静态内存是系统自动分配,由系统自动释放;
动态内存是手动分配,手动释放; -
静态内存是在栈分配的,动态内存是在堆分配的;
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;
}
运行结果