c语言 内存管理(malloc, calloc, free)

在C语言中,内存管理是一个核心概念,因为C让程序员直接控制内存的分配和释放。以下是 malloccallocfree 的详细说明:

1. malloc - 内存分配

功能:

分配指定字节数的内存块,不初始化内存内容。

语法:

cpp 复制代码
void* malloc(size_t size);

示例:

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

int main() {
    // 分配一个整数的内存
    int *ptr = (int*)malloc(sizeof(int));
    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    
    *ptr = 100;
    printf("值: %d\n", *ptr);
    
    free(ptr); // 释放内存
    return 0;
}

2. calloc - 分配并初始化内存

功能:

分配指定数量和大小的内存块,并将所有位初始化为0。

语法:

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

示例:

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

int main() {
    // 分配5个整数的数组,全部初始化为0
    int *arr = (int*)calloc(5, sizeof(int));
    if (arr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    
    for(int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, arr[i]); // 全部为0
    }
    
    free(arr);
    return 0;
}

3. free - 释放内存

功能:

释放之前分配的内存块。

语法

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

重要规则:

  • 只能释放通过 malloccallocrealloc 分配的内存

  • 不能重复释放同一块内存

  • 释放后应将指针设为NULL

综合示例

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

int main() {
    int n, i;
    
    printf("输入数组大小: ");
    scanf("%d", &n);
    
    // 使用malloc分配内存
    int *arr1 = (int*)malloc(n * sizeof(int));
    if(arr1 == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    
    printf("malloc分配的内容(未初始化):\n");
    for(i = 0; i < n; i++) {
        printf("%d ", arr1[i]); // 可能是随机值
    }
    printf("\n");
    
    // 使用calloc分配内存
    int *arr2 = (int*)calloc(n, sizeof(int));
    if(arr2 == NULL) {
        printf("内存分配失败!\n");
        free(arr1);
        return 1;
    }
    
    printf("calloc分配的内容(初始化为0):\n");
    for(i = 0; i < n; i++) {
        printf("%d ", arr2[i]); // 全部为0
    }
    printf("\n");
    
    // 重新分配内存 (realloc)
    int *arr3 = (int*)realloc(arr2, 2 * n * sizeof(int));
    if(arr3 == NULL) {
        printf("内存重新分配失败!\n");
        free(arr1);
        free(arr2);
        return 1;
    }
    
    printf("重新分配后的数组:\n");
    for(i = 0; i < 2 * n; i++) {
        printf("%d ", arr3[i]);
    }
    printf("\n");
    
    // 释放所有内存
    free(arr1);
    free(arr3);
    
    // 将指针设为NULL避免悬空指针
    arr1 = NULL;
    arr3 = NULL;
    
    return 0;
}

最佳实践和注意事项

1. 总是检查返回值

cpp 复制代码
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
    // 处理分配失败的情况
}

2. 避免内存泄漏

cpp 复制代码
// 错误示例
void leak_memory() {
    int *ptr = (int*)malloc(100 * sizeof(int));
    // 忘记调用 free(ptr)
}

// 正确示例
void no_leak() {
    int *ptr = (int*)malloc(100 * sizeof(int));
    if (ptr != NULL) {
        // 使用内存
        // ...
        free(ptr); // 及时释放
        ptr = NULL; // 避免悬空指针
    }
}

3. 不要重复释放

cpp 复制代码
int *ptr = (int*)malloc(sizeof(int));
free(ptr);
// free(ptr); // 错误!重复释放

4. 动态数组示例

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

int main() {
    int size;
    printf("输入数组大小: ");
    scanf("%d", &size);
    
    // 动态分配数组
    double *scores = (double*)malloc(size * sizeof(double));
    if (scores == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    
    // 输入数据
    for (int i = 0; i < size; i++) {
        printf("输入分数 %d: ", i + 1);
        scanf("%lf", &scores[i]);
    }
    
    // 计算平均值
    double sum = 0;
    for (int i = 0; i < size; i++) {
        sum += scores[i];
    }
    printf("平均分: %.2f\n", sum / size);
    
    free(scores);
    return 0;
}

alloc vs calloc 对比

特性 malloc calloc
初始化 不初始化 初始化为0
参数 一个参数(总字节数) 两个参数(元素个数, 元素大小)
性能 稍快 稍慢(因为要初始化)
使用场景 需要手动初始化时 需要零初始化时

掌握这些内存管理函数对于编写高效、稳定的C程序至关重要。

相关推荐
爱码小白3 分钟前
Python 异常处理 完整学习笔记
开发语言·python
c++之路18 分钟前
C++20概述
java·开发语言·c++20
芝士就是力量啊 ೄ೨32 分钟前
Python如何编写一个简单的类
开发语言·python
逻辑驱动的ken43 分钟前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
MoonBit月兔44 分钟前
「Why MoonBit 」第一期——Singularity Note AI 学习助手
开发语言·人工智能·moonbit
木木_王1 小时前
嵌入式Linux学习 | 数据结构 (Day05) 栈与队列详解(原理 + C 语言实现 + 实战实验 + 易错点剖析)
linux·c语言·开发语言·数据结构·笔记·学习
冷雨夜中漫步1 小时前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
超龄编码人1 小时前
Qt Widgets Designer QTabWidget无法添加布局
开发语言·qt
直奔標竿1 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
Python大数据分析@1 小时前
CLI一键采集,使用Python搭建TikTok电商爬虫Agent
开发语言·爬虫·python