亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

C 语言动态内存分鱁全解:malloc、calloc、realloc、free 实战指南

深入动态内存分配前,先理解 C 语言内存管理机制。

C 语言内存管理原理

基本类型变量声明时,编译器自动在 栈 上分配空间。例如 float 通常占 4 字节(平台相关)。可用 sizeof 验证:

#include <stdio.h>
int main() {
    float x;
    printf("The size of float is %d bytes", sizeof(x));
    return 0;
}

输出:

The size of float is 4 bytes

指定大小的数组也在栈上连续分配,每元素占其类型大小:

#include <stdio.h>
int main() {
    float arr[10];
    printf("The size of the float array with 10 elements is %d", sizeof(arr));
    return 0;
}

结果:

The size of the float array with 10 elements is 40

栈分配虽自动,但许多程序需要运行时才知大小的内存。这由 动态内存分配 解决,使用 堆 而非栈。

C 语言动态内存分配

动态分配手动请求/释放内存,用指针追踪堆上分配块。标准库提供四大函数:

逐一详解。

malloc() 函数

malloc() 全称“memory allocation”。保留指定字节块并返回指针,通常强转为目标类型:

ptr = (cast_type *) malloc(byte_size);

示例:

#include <stdlib.h>
int main(){
    int *ptr;
    ptr = malloc(15 * sizeof(*ptr)); /* 15 个整数 */
    if (ptr != NULL) {
        *(ptr + 5) = 480; /* 第 6 个元素 */
        printf("Value of the 6th integer is %d", *(ptr + 5));
    }
}

输出:

Value of the 6th integer is 480

要点:

  1. 用 sizeof(*ptr) 使代码对类型变更健壮
  2. 检查 NULL 返回值以捕获分配失败
  3. 分配内存连续,可视为数组用指针算术访问

动态分配不限基本类型,结构体、字符数组均适用。

free() 函数

malloc()、calloc()、realloc() 分配的内存必须显式释放防泄漏。free() 完成此任务:

#include <stdio.h>
int main() {
    int* ptr = malloc(10 * sizeof(*ptr));
    if (ptr != NULL){
        *(ptr + 2) = 50;
        printf("Value of the 2nd integer is %d", *(ptr + 2));
    }
    free(ptr);
}

输出:

Value of the 2nd integer is 50

calloc() 函数

calloc() 分配多个等大块并将每字节置零,适合需零初始化的数组/结构体:

ptr = (cast_type *) calloc(n, size);

示例 – 等差数列求和:

#include <stdio.h>
int main() {
    int i, *ptr, sum = 0;
    ptr = calloc(10, sizeof(int));
    if (ptr == NULL) {
        printf("Error! memory not allocated.");
        exit(0);
    }
    for (i = 0; i < 10; ++i) {
        *(ptr + i) = i;
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

结果:

Sum = 45

calloc() vs malloc()

关键差异:

realloc() 函数

realloc() 调整现有分配大小并保留内容:

ptr = realloc(ptr, newsize);

示例 – 扩展字符串缓冲区:

#include <stdio.h>
int main () {
    char *ptr = malloc(10);
    strcpy(ptr, "Programming");
    ptr = realloc(ptr, 20); // 扩容
    strcat(ptr, " In 'C'");
    printf("%s, Address = %u", ptr, ptr);
    free(ptr);
    return 0;
}

重分配失败时 realloc() 返回 NULL 且原块保持有效。

动态数组

动态数组允许元素数量运行时增长,算法与数据结构常用模式:

#include <stdio.h>
int main() {
    int *arr_dynamic = NULL;
    int elements = 2, i;
    arr_dynamic = calloc(elements, sizeof(int));
    for (i = 0; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    elements = 4;
    arr_dynamic = realloc(arr_dynamic, elements * sizeof(int));
    printf("After realloc\n");
    for (i = 2; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    free(arr_dynamic);
}

结果:

arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

总结

C语言

  1. 理解 ROM、PROM、EPROM 与 EEPROM:设计、编程与识别
  2. C# 基础:输入输出核心技巧完全指南
  3. 掌握 C# using 指令:命名空间导入、别名与静态导入全解析
  4. C++ 动态内存管理:new 与 delete 专家级实战指南
  5. C 语言用户自定义函数四大模式对比:参数与返回值的设计权衡
  6. C语言动态内存分配完全指南:malloc、calloc、realloc 与 free
  7. 精通C标准库函数:实战指南
  8. C++ 动态数组分配实战指南:new/delete、初始化、扩容与内存管理
  9. C++ 函数详解:从声明到调用的实战指南
  10. C 语言函数详解:定义、声明、调用与参数传递
  11. C 语言动态内存管理:calloc、malloc 与 free 完全解析
  12. C++动态内存管理精要:栈与堆、new/delete、数组与对象分配实战