【C语言】动态内存分配
动态内存分配
背景
以前如果需要从键盘输入数组的范围并定义是行不通的。
只能定义一个较大的值作为数组的大小,此时数组长度必须在编译的时候 确定
而动态数组 允许你在程序运行过程中 (Runtime)才决定数组的大小。
有:
1 | 语言: C)产生动态数组,编写程序,输入数组大小后,通过动态分配内存函数malloc产生数组。 |
代码实现
1 |
|
(int*)malloc(size * sizeof(int))这一句话中的占用的字节数可不可以输入数字来替代?
可以,但不推荐。sizeof(int) 的作用是获取 int 类型在当前计算机上占用的字节数。
- 在现代常见的电脑上,
int通常是 4 字节。 - 所以写
malloc(size * 4)和malloc(size * sizeof(int))效果是一样的。
为什么不推荐写死数字? 因为可移植性(Portability) 。
- 有些老式嵌入式系统或特殊的单片机,
int可能是 2 字节。 - 如果你写死了
4,放到那台机器上,你的数组就会变得比预期大,或者出现内存对齐错误。 - 使用
sizeof(int),编译器会自动帮你判断当前机器是几字节,代码更健壮。
可不可以换成char,即给char类型的数组分配内存的时候?
完全可以
NULL这个到底是啥?
在 C 语言的定义里,它长这样:
1 |
你可以把它理解为一个**“无效地址”** 或者**“空地址”** 。
- 在内存里,地址
0是受操作系统严格保护的,任何程序都不允许读写这个地址。 - 所以,当我们把一个指针指向
NULL,就是明确表示:这个指针目前不指向任何有效的东西 。
NULL 的值: 在 C 语言中,NULL 是一个宏,用于表示空指针。在大多数编译器和标准库实现中,它通常被定义为整数 0 或者 ((void *)0)。无论哪种定义,其底层的数值表示都是 0 。
打印结果 : 当 printf("%d\n", NULL); 执行时,它会将 NULL 对应的值(即 0)按照整数格式打印出来。因此,输出结果将会是 0。
array == NULL是怎么实现检查内存是否分配成功的?
malloc 的内部逻辑大致如下(简化版):
- 你去告诉操作系统:“我要 100 字节内存”。
- 操作系统去堆(Heap)里找,看有没有连续的 100 字节空地。
- 情况一(成功): 找到了。操作系统把这块地的首地址 (比如
0x12345678)返回给你。- 这时
array等于0x12345678,不等于NULL。
- 这时
- 情况二(失败): 内存满了,或者你要的太大了(比如你要 1000GB),实在找不到了。操作系统就会返回
NULL。- 这时
array等于NULL。
- 这时
所以,if (array == NULL) 这行代码就是在问:“操作系统,你刚才给我分配内存的时候,是拒绝我了吗?”
free(array);中为什么动态分配的内存必须要释放?
打个比方:酒店 vs. 家
- 栈内存(Stack - 也就是普通的变量): 像是你的家 。
- 你回家(函数开始),住进去,出门(函数结束),灯自动关,房间自动空出来。系统自动管理,不需要你操心。
- 堆内存(Heap - 也就是 malloc 的内存): 像是住酒店 。
malloc就是你去前台办理入住(申请房卡) 。- 你在房间里睡觉、放东西(存数组数据),这叫“使用”。
- 关键点来了: 当你离开酒店(程序跑去执行别的函数了),如果你不去前台退房(free) ,酒店系统会认为你还住在里面 。
什么是内存泄漏(Memory Leak)?
你走了,但没退房。
- 对于你(程序)来说: 你的指针变量
array可能在函数结束时销毁了(你把房卡丢了)。你再也找不到那个房间了,你也无法再使用它。 - 对于酒店(操作系统)来说: 电脑显示那个房间“占用中”。如果有新客人来,酒店不能把这个房间给别人。
后果: 如果你写了一个死循环或者服务器程序(长期运行),不断地 malloc 却不 free(不断开房不退房),酒店的房间很快就会全部爆满。 最终,物理内存被耗尽 ,操作系统会强制杀掉你的程序,甚至导致电脑死机。这就是内存泄漏 。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 王总的博客!




