c语言malloc函数用法

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 C语言 正文

malloc 是 C 语言动态内存分配的核心函数之一,它允许程序员在程序运行时(而不是编译时)申请一块指定大小的内存空间,这对于处理不确定大小的数据(如用户输入、文件内容等)至关重要。

c语言malloc函数用法
(图片来源网络,侵删)

malloc 是什么?

malloc 的全称是 memory allocation(内存分配),它定义在头文件 <stdlib.h> 中。

它的作用是:在 上分配一块连续的内存空间,并返回一个指向这块内存起始地址的 void* 类型的指针。

关键点:

  • 堆内存:与栈内存不同,堆内存由程序员手动管理,生命周期从 malloc 调用开始,直到 free 调用或程序结束。
  • *`void指针**:malloc` 返回的是一个通用指针,它可以指向任何类型的数据,在使用时,我们通常需要将其强制转换为我们需要的具体类型的指针。

函数原型

void *malloc(size_t size);
  • 参数:
    • size_t size: 你想要分配的内存空间的大小,以 字节 为单位。
  • 返回值:
    • 成功时: 返回一个指向分配好的内存块起始地址的 void* 指针。
    • 失败时: 如果堆空间不足,无法满足分配请求,malloc 会返回 NULL 指针,这是一个非常重要的返回值,必须进行检查!

基本用法步骤(四步曲)

使用 malloc 的标准流程如下:

第 1 步:包含头文件

必须包含 <stdlib.h>,因为 mallocfree 等函数都在这个头文件中声明。

#include <stdlib.h> // 或者 #include <malloc.h> 在某些系统中也可以

第 2 步:声明指针

声明一个与你想要存储的数据类型相匹配的指针。

int *ptr; // 声明一个指向整型的指针

第 3 步:调用 malloc 并检查返回值

使用 sizeof 运算符来计算所需内存的大小,并将返回的 void* 指针强制转换为你需要的类型。务必检查返回值是否为 NULL

// 申请 sizeof(int) 字节的内存,并强制转换为 int*
ptr = (int *)malloc(sizeof(int));
// 检查内存是否分配成功
if (ptr == NULL) {
    printf("内存分配失败!\n");
    // 在这里可以采取错误处理措施,比如退出程序
    return 1; // 或 exit(1);
}

第 4 步:使用内存

你可以像使用普通数组或变量一样,通过指针来访问和使用这块内存。

*ptr = 100; // 将 100 存入 ptr 指向的内存中
printf("ptr 指向的值是: %d\n", *ptr);

第 5 步:释放内存

当你不再需要这块内存时,必须 使用 free 函数将其释放,否则,就会造成 内存泄漏

free(ptr); // 释放 ptr 指向的内存
ptr = NULL; // 这是一个好习惯,将指针置为 NULL,防止成为“野指针”

完整示例代码

示例 1:分配单个变量

#include <stdio.h>
#include <stdlib.h>
int main() {
    // 1. 声明指针
    int *number_ptr;
    // 2. 分配内存
    number_ptr = (int *)malloc(sizeof(int));
    // 3. 检查是否分配成功
    if (number_ptr == NULL) {
        fprintf(stderr, "错误:内存分配失败,\n");
        return 1;
    }
    // 4. 使用内存
    *number_ptr = 42;
    printf("分配的整数值是: %d\n", *number_ptr);
    // 5. 释放内存
    free(number_ptr);
    number_ptr = NULL; // 推荐做法
    return 0;
}

示例 2:分配一个数组

这是 malloc 最常见的用法之一,用于创建动态数组。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int n;
    int *array_ptr;
    printf("请输入数组的大小: ");
    scanf("%d", &n);
    // 1. 分配 n 个整型的内存空间
    array_ptr = (int *)malloc(n * sizeof(int));
    // 2. 检查是否分配成功
    if (array_ptr == NULL) {
        fprintf(stderr, "错误:内存分配失败,\n");
        return 1;
    }
    // 3. 使用内存(像普通数组一样)
    printf("请输入 %d 个整数:\n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &array_ptr[i]);
    }
    printf("你输入的数组是:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", array_ptr[i]);
    }
    printf("\n");
    // 4. 释放内存
    free(array_ptr);
    array_ptr = NULL;
    return 0;
}

重要注意事项和常见错误

错误 1:忘记检查 NULL 返回值

这是最常见也是最危险的错误。malloc 失败而你没有检查,后续使用 NULL 指针会导致程序崩溃(段错误)。

// 错误示例
int *p = (int *)malloc(1000000000 * sizeof(int)); // 尝试分配过大内存
*p = 10; // p 是 NULL,这里会直接导致程序崩溃

错误 2:内存泄漏

分配了内存但没有 free,或者 free 的逻辑有误,导致这块内存永远无法被回收,直到程序结束,在长时间运行的程序(如服务器、游戏)中,内存泄漏是致命的。

// 错误示例
void leaky_function() {
    int *p = (int *)malloc(sizeof(int));
    *p = 5;
    // 函数结束,p 被销毁,但分配的内存没有释放!
    // 这块内存就泄漏了。
}

错误 3:重复释放

对同一块内存调用两次 free 会导致 未定义行为,通常会使程序崩溃。

// 错误示例
int *p = (int *)malloc(sizeof(int));
free(p);
free(p); // 第二次 free 是错误的!

错误 4:释放后继续使用(野指针)

释放内存后,指针变量本身并没有被销毁,它仍然保存着那块已释放内存的地址,继续使用这个指针就是访问非法内存。

// 错误示例
int *p = (int *)malloc(sizeof(int));
*p = 10;
free(p); // 内存已释放
*p = 20; // 错误!访问了已释放的内存,可能导致程序崩溃或数据污染

最佳实践:释放内存后,立即将指针置为 NULL

free(p);
p = NULL; // p 是 NULL,访问 *p 会在编译时或运行时被检查出来

错误 5:计算 sizeof 时的错误

在分配数组时,常见的错误是写成 malloc(n),这只会分配 n 个字节,而不是 n 个元素,正确的做法是 n * sizeof(数据类型)

// 错误示例
int *p = (int *)malloc(10); // 只分配了 10 字节,只能存下 2 或 3 个 int
// 正确示例
int *p = (int *)malloc(10 * sizeof(int)); // 分配了 10 个 int 的空间

malloccalloc 的区别

malloccalloc 都是动态内存分配函数,但 calloc 有两个主要区别:

  1. 参数不同calloc 接受两个参数:元素个数 (num) 和每个元素的大小 (size)。
    void *calloc(size_t num, size_t size);
  2. 初始化calloc 会将分配的内存块中的所有位都初始化为 ,而 malloc 不会进行初始化,内存中是随机的“垃圾值”。

示例

// 使用 malloc,内存未初始化
int *p_malloc = (int *)malloc(5 * sizeof(int));
// p_malloc[0] 的值是随机的
// 使用 calloc,内存被初始化为 0
int *p_calloc = (int *)calloc(5, sizeof(int));
// p_calloc[0] 的值是 0
特性 malloc
头文件 #include <stdlib.h>
功能 在堆上分配指定字节数的内存
参数 size_t size (总字节数)
返回值 成功返回 void*,失败返回 NULL
内存初始化 不确定
配套函数 free() 用于释放内存
核心原则 谁分配,谁释放,每次 malloc 都必须对应一次 free

掌握 malloc 是学习 C 语言高级特性的关键一步,请务必牢记其用法和注意事项,养成良好的内存管理习惯。

-- 展开阅读全文 --
头像
织梦后台添加不了文章
« 上一篇 03-25
c语言课程设计图书管理系统
下一篇 » 03-25

相关文章

取消
微信二维码
支付宝二维码

目录[+]