跳转到内容

C 语言动态内存分配

来自代码酷

模板:Note

C语言动态内存分配[编辑 | 编辑源代码]

动态内存分配是C语言中通过运行时请求操作系统分配内存的机制,与编译时确定大小的静态内存分配形成对比。该技术允许程序根据实际需求灵活管理内存,是构建动态数据结构(如链表、树等)的核心技术。

核心概念[编辑 | 编辑源代码]

在C语言中,动态内存分配通过四个标准库函数实现,均在<stdlib.h>中声明:

函数 作用 生命周期
malloc() 分配未初始化的内存块 直到调用free()
calloc() 分配并清零的内存块 直到调用free()
realloc() 调整已分配内存的大小 新指针替代原指针
free() 释放已分配的内存 立即生效

内存布局图示[编辑 | 编辑源代码]

graph TD A[程序内存布局] --> B[代码区] A --> C[静态存储区] A --> D[栈] A --> E[堆] E -->|malloc/calloc/realloc| F[动态分配内存块] F -->|free| E

函数详解[编辑 | 编辑源代码]

malloc()[编辑 | 编辑源代码]

分配指定字节的未初始化内存块:

#include <stdlib.h>
void *malloc(size_t size);

示例:

int *arr = (int*)malloc(5 * sizeof(int)); // 分配20字节(假设int为4字节)
if (arr == NULL) {
    // 处理分配失败
}

calloc()[编辑 | 编辑源代码]

分配并清零的内存块,参数为元素个数和单个元素大小:

void *calloc(size_t num, size_t size);

示例:

double *matrix = (double*)calloc(10, sizeof(double)); // 分配归零的10个double

realloc()[编辑 | 编辑源代码]

调整已分配内存块的大小:

void *realloc(void *ptr, size_t new_size);

示例:

int *arr = (int*)malloc(5 * sizeof(int));
arr = (int*)realloc(arr, 10 * sizeof(int)); // 扩展到40字节

free()[编辑 | 编辑源代码]

释放动态分配的内存:

void free(void *ptr);

重要规则:

  • 只能释放由malloc/calloc/realloc返回的指针
  • 禁止重复释放同一指针
  • 释放后应将指针置为NULL

内存管理原理[编辑 | 编辑源代码]

动态内存分配在区域进行,其特点包括:

  • 分配/释放需要手动管理
  • 内存碎片化风险
  • 分配失败返回NULL指针

内存分配器工作原理:

sequenceDiagram participant Program participant Allocator participant OS Program->>Allocator: malloc(100) Allocator->>OS: sbrk()/mmap() OS-->>Allocator: 内存块地址 Allocator-->>Program: 返回指针

最佳实践[编辑 | 编辑源代码]

错误处理模式[编辑 | 编辑源代码]

int *buffer = (int*)malloc(large_size);
if (buffer == NULL) {
    perror("内存分配失败");
    exit(EXIT_FAILURE); // 或执行其他恢复逻辑
}

内存泄漏检测[编辑 | 编辑源代码]

常见内存问题包括:

  • 忘记释放内存
  • 使用已释放内存
  • 越界访问

使用工具如Valgrind检测:

valgrind --leak-check=full ./your_program

实际应用案例[编辑 | 编辑源代码]

动态数组实现[编辑 | 编辑源代码]

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int *data;
    size_t size;
    size_t capacity;
} DynamicArray;

void initArray(DynamicArray *arr, size_t initialCapacity) {
    arr->data = (int*)malloc(initialCapacity * sizeof(int));
    arr->size = 0;
    arr->capacity = initialCapacity;
}

void pushBack(DynamicArray *arr, int value) {
    if (arr->size >= arr->capacity) {
        arr->capacity *= 2;
        arr->data = (int*)realloc(arr->data, arr->capacity * sizeof(int));
    }
    arr->data[arr->size++] = value;
}

void freeArray(DynamicArray *arr) {
    free(arr->data);
    arr->data = NULL;
    arr->size = arr->capacity = 0;
}

性能考量[编辑 | 编辑源代码]

动态分配涉及系统调用,比栈分配更耗时。典型操作时间(纳秒级): Tmalloc100300nsvsTstack13ns

进阶主题[编辑 | 编辑源代码]

  • 内存池技术
  • 自定义分配器实现
  • 垃圾收集算法基础
  • 多线程环境下的内存管理

页面模块:Message box/ambox.css没有内容。

  • 检查分配返回值
  • 避免野指针
  • 及时释放内存
  • 使用静态分析工具