动态内存分配
动态内存分配
背景
以前如果需要从键盘输入数组的范围并定义是行不通的。
只能定义一个较大的值作为数组的大小,此时数组长度必须在编译的时候确定
而动态数组允许你在程序运行过程中(Runtime)才决定数组的大小。
有:
1 | |
代码实现
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(不断开房不退房),酒店的房间很快就会全部爆满。 最终,物理内存被耗尽,操作系统会强制杀掉你的程序,甚至导致电脑死机。这就是内存泄漏。
动态内存分配
http://example.com/2025/12/17/动态内存分配/