传统数组的缺点
- 数组长度必须事先指定且只能是常整数,不能是变量
int a[5]; √ int len = 5; int a[len]; ×
- 传统形式定义的数组,该数组所占用内存空间无法手动释放
int a[5] = {1, 2, 3, 4, 5};
- 在函数运行期间,这 20 个字节的存储空间无法手动编程释放掉。系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统所释放
- 数组的长度不能在函数运行的过程中动态的扩充或缩小。数组的长度一旦定义,直至程序运行结束,都不能再更改
- 传统方式定义的数组不能跨函数使用
- [f 函数] 定义的数组,在 [f 函数] 运行期间可以被 [g 函数] 使用(f 内部调用 g)
- 但当 [f 函数] 运行完毕之后,[f 函数] 所占用的内存被释放掉
- 继而 [f 函数] 定义的数组也就无法再被其他函数所使用
动态内存分配
动态数组很好的解决了传统数组(也叫静态数组)的上述缺陷
Quick Start
- malloc()
- malloc:memory allocate 内存分配
- 使用 malloc 函数,必须要添加
<malloc.h>
头文件 - malloc 函数只有一个形参,并且形参是整型,表示要分配的字节数目
- malloc 只返回第一个字节的地址
(int*)
强制类型转换的作用- malloc 了 4 个字节,但 malloc 只返回第一个字节的地址
- 需要强转来说明第 1 个字节的地址所指向的变量占用几个字节
- 第 2 行一共分配出去几个字节?
- 8 个字节,p 变量占 4 个字节,p 所指向的内存空间也占 4 个字节
- p 本身所占用的内存空间是静态分配的
- p 所指向的内存空间是动态分配的
- 补充:
realloc(指针名ptr, 目标字节数size)
- 实现动态扩充/缩小指针所指向的内存空间大小,将指针指向的内存大小增大或缩小到 size
- 这时新的空间不一定是在原来 ptr 的空间基础上,增加或减小长度来得到。而有可能(特别是在用 realloc 来增大 ptr 的内存空间的时候)会是在一个新的内存区域分配一个大空间,然后将原来 ptr 空间的内容拷贝到新内存空间的起始部分,然后将原来的空间释放掉
- 一般要将 realloc 的返回值用一个指针来接收
动态构造一维数组
静态内存和动态内存的比较
- 静态内存
- 是由系统自动分配,也由系统进行释放
- 是在【栈】中分配的(压栈,出栈)
- 动态内存
- 手动分配 malloc,手动释放 free(内存泄露)
- 是在【堆】中分配的