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 分钟前
Next.js 16.3 新特性全解析 AI 驱动开发与 Instant Navigations 实战指南
开发语言·javascript·人工智能
小小编程路5 分钟前
Java super 关键字详解:用法、场景与常见误区
java·开发语言
薛定猫AI21 分钟前
【技术干货】大模型检查点可靠性评测:基于 Python 构建幻觉与指令遵循测试
开发语言·python
文祐28 分钟前
C语言利用数组计算矩阵乘法
c语言·开发语言·矩阵
matlab代码30 分钟前
Matlab基于主成分分析PCA人脸识别系统(GUI界面)【源码44期】
开发语言·matlab·人脸识别
m0_7381207233 分钟前
AI安全实战系列(四):Lab04 Multi-Agent——多智能体攻击分析
服务器·开发语言·人工智能·安全·网络安全·语言模型
ch.ju38 分钟前
Java Programming Chapter 4——Anonymous inner class
java·开发语言
Mr__Miss1 小时前
Java 随机数生成器选型指南:Random、ThreadLocalRandom 与 SecureRandom
java·开发语言·python
Risehuxyc1 小时前
PHP数据类型
开发语言·php
Wang's Blog1 小时前
Go-Zero基础入门5: 探究go-zero如何基于gRPC扩展客户端
开发语言·后端·golang·go-zero