blog/_posts/编程/C语言/memory-manager.md
2025-02-17 13:45:42 +08:00

3.4 KiB
Raw Permalink Blame History

title date tags
🤲C语言程序的内存管理 2025-02-16
C语言
嵌入式

内存分布说明

C语言程序的内存通常分为以下几个区域

  • Stack

    1. 用于存储局部变量、函数参数和函数调用的上下文。
    2. 内存由编译器自动分配和释放。
    3. 大小有限通常较小几MB
  • Heap

    1. 用于动态内存分配。
    2. 内存由程序员手动管理(分配和释放)。
    3. 大小较大,受系统内存限制。
  • 全局/静态区Global/Static Area

    1. 用于存储全局变量和静态变量。
    2. 内存在程序启动时分配,程序结束时释放。
  • 常量区Constant Area

    1. 用于存储字符串常量和其他常量。
    2. 内存在程序启动时分配,程序结束时释放。
  • 代码区Code Area用于存储程序的二进制代码。

内存函数

动态内存管理

  1. malloc分配指定大小的内存块。
// size需要分配的内存大小以字节为单位void* malloc(size_t size);
// 返回值:
// 成功:返回指向分配内存的指针。
// 失败:返回 NULL。
// 示例:
int* ptr = (int*)malloc(10 * sizeof(int));  // 分配10个int大小的内存
if (ptr == NULL) {
    // 处理内存分配失败
}
  1. calloc:分配指定数量的内存块并将内存初始化为0

    void* calloc(size_t num, size_t size);
    // 参数:
    //     num需要分配的元素数量。
    //     size每个元素的大小以字节为单位    // 返回值:
    //     成功:返回指向分配内存的指针。
    //     失败:返回 NULL。
    //示例:
    int* ptr = (int*)calloc(10, sizeof(int));  // 分配10个int大小的内存并初始化为0
    if (ptr == NULL) {
        // 处理内存分配失败
    }
  1. realloc调整已分配内存块的大小。
    // 参数:
    //     ptr指向已分配内存的指针。
    //     size新的内存大小以字节为单位    // 返回值:
    //     成功:返回指向新内存的指针。
    //     失败:返回 NULL原内存块保持不变。
    void* realloc(void* ptr, size_t size);

    // 示例:
    int* ptr = (int*)malloc(10 * sizeof(int));
    ptr = (int*)realloc(ptr, 20 * sizeof(int));  // 将内存块大小调整为20个int
    if (ptr == NULL) {
        // 处理内存分配失败
    }

  1. free释放动态分配的内存。
    // 参数:
    // ptr指向需要释放的内存块的指针。
    // 注意:
    //    只能释放由 malloc、calloc 或 realloc 分配的内存。
    //    释放后应将指针设置为 NULL以避免悬空指针。
    void free(void* ptr);
    //示例:
    int* ptr = (int*)malloc(10 * sizeof(int));
    // 使用内存
    free(ptr);  // 释放内存
    ptr = NULL; // 避免悬空指针

内存管理最佳实践

  1. 在定义指针时初始化为 NULL避免野指针的出现。
  2. 每次调用 malloc、calloc 或 realloc 后检查返回值是否为 NULL以避免内存分配失败。
  3. 尽量减少频繁的内存分配和释放,尤其是小块内存。
  4. 使用内存检测工具(如 Valgrind检查内存泄漏和越界访问
  5. 释放内存后立即将指针设置为 NULL避免悬空指针。
  6. 确保每次 malloc 或 calloc 后都有对应的 free 调用,以避免内存泄露。