C 语言 动态内存分配

一、核心作用

普通数组大小必须编译期确定;

动态内存可以程序运行时申请内存,堆(heap)上分配,用完手动释放。

bash 复制代码
头文件:<stdlib.h>

二、4 个核心函数

1. malloc

• 功能:分配size 字节连续内存,不初始化,内容随机垃圾值

• 返回:成功→内存首地址;失败→NULL

bash 复制代码
// 分配能存5个int的空间
int *p = (int *)malloc(5 * sizeof(int));
if(p == NULL)

{

    // 必须判空!
    perror("malloc fail");
    return -1;
}

2. calloc

复制代码
void *calloc(size_t num, size_t size);

• 功能:分配num个、每个size字节的内存,自动初始化为 0

bash 复制代码
int *p = (int *)calloc(5, sizeof(int));

3. realloc 重新调整大小

复制代码
void *realloc(void *ptr, size_t new_size);

• 扩容 / 缩容已有动态内存

• 注意:

  1. 不要直接 p = realloc(p, ...),失败会返回 NULL,丢失原地址造成内存泄漏

  2. 扩容不一定原地,可能拷贝数据到新地址

bash 复制代码
int *tmp = realloc(p, 10 * sizeof(int));
if(tmp != NULL){
    p = tmp;
}

4. free 释放内存

bash 复制代码
void free(void *ptr);

• 归还堆内存,必须配对使用

• 规则:

  • free 只能释放 malloc/calloc/realloc 得到的指针
  • 不能重复 free、不能 free 栈上变量
  • free 之后指针变成野指针,建议手动置 NULL
bash 复制代码
free(p);
p = NULL;

三、完整示例

bash 复制代码
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int n = 5;
    // 堆区申请内存,不初始化
    int *arr = (int *)malloc(n * sizeof(int));

    // ⚠重点:必须判断分配是否成功
    if(arr == NULL){
        printf("malloc fault\n");
        return 1; // 异常退出
    }

    for(int i = 0; i < n; i++){
        arr[i] = i + 1;
    }

    // ⚠易错:realloc先用临时指针接收,失败不会覆盖原地址
    int *tmp = realloc(arr, 10 * sizeof(int));
    if(tmp == NULL)
    {
        printf("realloc fault\n");
        free(arr);
        arr = NULL;
        return 1;
    }
    arr = tmp;

    // ⚠扩容新增区域数据随机,如需使用要手动赋值

    free(arr);      // ⚠堆内存使用完必须释放
    arr = NULL;     // ⚠防止野指针

    return 0; // 正常退出
}

四、常见坑

  1. 忘记 free → 内存泄漏

  2. free 之后继续使用指针 → 野指针访问(程序崩溃)

  3. 重复 free 同一地址

  4. realloc 直接赋值原指针,分配失败丢失内存

  5. 不判断 malloc 返回 NULL,内存不足直接崩溃

  6. sizeof( )写错,大小分配不足造成越界

五、栈内存 vs 堆内存

区域 分配方式 释放 生命周期
栈 (stack) 局部数组、局部变量 函数结束自动回收 函数内有效
堆 (heap) malloc/calloc 手动 free 直到 free 或程序结束
相关推荐
前端 贾公子17 分钟前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_9622035119 分钟前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理39 分钟前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
专注仿真1 小时前
Spring AI 实现智能对话系统项目指南
数据结构·spring·机器学习
roman_日积跬步-终至千里1 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
靠沿1 小时前
贪心算法专题(二)
算法·贪心算法
落魄大学生之流水线上谋生计1 小时前
LangGraph 基本用法指南
java·windows·python·langchain
2601_962128411 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存
间歇性努力持续性发呆的野生快乐选手2 小时前
高级数据结构:树状数组
数据结构
Dovis(誓平步青云)2 小时前
折叠屏悬停看视频,上半屏和下半屏应该各做什么
android·java·服务器·开发语言·安全·音视频