一、动态内存分配
1. malloc函数
malloc(memory allocation,内存分配)函数是C语言标准库中的一个函数,用于在程序运行时动态分配一块指定大小的内存区域。这块内存是在堆(heap)上分配的,与栈上的内存不同,它的生命周期由程序员控制,可以手动分配和释放。malloc 函数的声明在 stdlib.h 头文件中。
malloc 的基本用法
1 | #include <stdlib.h> |
参数:
size: 要分配的内存大小,以字节为单位。
返回值:
- 成功时,返回一个指向分配内存块的指针,该指针的类型为
void*(可以强制转换为任何类型的指针)。 - 如果分配失败(比如系统内存不足),则返回
NULL。
示例代码:
1 |
|
在这个例子中,malloc 分配了一个能容纳 5 个 int 类型元素的内存空间。注意,分配内存后应立即检查是否分配成功(返回值是否为 NULL),并且在使用完分配的内存后,应该使用 free 函数释放内存,以避免内存泄漏。
malloc 的优点
- 灵活的内存管理:
malloc允许在运行时动态分配内存,尤其适用于数组大小在编译时不确定的情况。 - 堆上的大内存:与栈不同,堆可以存储比栈更大的数据。使用
malloc可以避免栈溢出,适合处理大数据或需要长期保留的数据。 - 可移植性:
malloc是标准库函数,跨平台可用。
malloc 的缺点
- 手动管理内存:程序员必须手动释放内存(使用
free函数)。未及时释放内存会导致内存泄漏,程序运行时间长了可能耗尽系统内存。 - 分配失败风险:
malloc在分配失败时返回NULL,程序员需要处理这种情况。忽略分配失败的检查可能导致程序崩溃。 - 性能开销:动态内存分配在系统调用中有一定的性能开销,因此如果频繁分配和释放内存,性能可能受到影响。
常见的错误使用
- 忘记释放内存:导致内存泄漏。
- 二次释放内存:释放已经释放过的内存会导致程序运行错误。
- 使用未初始化的内存:
malloc只分配内存但不初始化,需要手动初始化或使用calloc。
总之,malloc 是C语言中用于动态内存管理的基础工具,但在使用时需要格外小心,以避免内存管理方面的错误。
2. 内存泄漏
程序作用:
- 用malloc获取100MB内存空间,返回地址赋值给p
- while循环可以分辨获取了几次空间
3. malloc申请的内存是否连续?
是的,malloc 函数分配的内存是连续的。
在 C 语言中,malloc 函数用于动态分配一块指定大小的内存区域,并返回一个指向该内存块的指针。malloc 保证返回的内存块是连续的,即在物理内存中是相邻的一块区域。这对于许多需要内存连续性的操作非常重要,例如在处理数组、矩阵等数据结构时。
4. 0 (Null)不是一个有效的地址
free(Null)
free(0)均是不会报错的。
因此,可以在定义指针时,赋值为零。
5. 常见问题
- malloc没有free, 残留内存垃圾,申请内存不释放,会造成内存泄漏,比如大型程序(服务器程序)
思考
1 |
|
在 C 语言中,指针相减操作会返回两个指针之间的距离,单位是数组元素的个数。
假设你有如下的代码:
1 | int a[] = {1, 2, 3, 4, 5}; |
p指向数组a的第一个元素,即a[0],地址为a。q指向a[5],也就是超出数组末尾的第一个地址(这个元素不存在,因为数组的有效下标是 0 到 4)。
接下来执行 q - p:
q指向&a[5],即a数组末尾后面的地址。p指向数组的第一个元素a[0]。
计算 q - p 时,它会计算两个指针之间相隔的元素个数。因此:
1 | q - p = 5 |
这是因为 q 指向的地址比 p 向后移动了 5 个整型元素的距离。
最终答案是:q - p = 5。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Turin's Blog!

![【stm32单片机】[操作系统][RT-Thread][3]线程通信](/img/blog_cover/rt-thread.jpg)