C 内存管理学习笔记

在 C 语言中,程序员需要自己手动管理内存的分配和释放。这是因为 C 语言的出发点是底层操作系统编程,需要保证程序的效率和稳定性,而手动管理内存可以更精细地控制程序的资源消耗。

内存分配函数

C 语言提供了以下几个函数用于动态内存分配:

malloc()

Copy Code
void *malloc(size_t size);
  • 功能:分配一块指定大小的内存空间。
  • 参数:size 表示需要分配的内存空间大小。
  • 返回值:返回一个指向分配内存起始地址的指针。如果分配失败,返回 NULL

例如:

cCopy Code
int *p = (int *)malloc(sizeof(int)); // 分配一个整型变量的大小 if (p == NULL) { printf("Memory allocation failed.\n"); return 1; } else { *p = 123; printf("Value of p: %d\n", *p); free(p); // 释放内存 }

calloc()

Copy Code
void *calloc(size_t num, size_t size);
  • 功能:分配一块指定数量和大小的内存空间,并将所有位初始化为零值。
  • 参数:num 表示需要分配的内存空间的数量,size 表示每个内存空间的大小。
  • 返回值:返回一个指向分配内存起始地址的指针。如果分配失败,返回 NULL

例如:

cCopy Code
int *p = (int *)calloc(5, sizeof(int)); // 分配包含 5 个整型变量的空间,所有位初始化为 0 if (p == NULL) { printf("Memory allocation failed.\n"); return 1; } else { for (int i = 0; i < 5; i++) { printf("Value of p[%d]: %d\n", i, p[i]); } free(p); // 释放内存 }

realloc()

Copy Code
void *realloc(void *ptr, size_t size);
  • 功能:重新分配已经分配的内存空间大小。
  • 参数:ptr 表示需要重新分配的内存指针,size 表示需要分配的内存空间大小。
  • 返回值:返回一个指向分配内存起始地址的指针。如果分配失败,返回 NULL

例如:

cCopy Code
int *p = (int *)malloc(sizeof(int)); // 分配一个整型变量的大小 if (p == NULL) { printf("Memory allocation failed.\n"); return 1; } else { *p = 123; printf("Value of p: %d\n", *p); p = (int *)realloc(p, sizeof(int) * 2); // 将内存空间重新分配为两个整型变量的大小 if (p == NULL) { printf("Memory reallocation failed.\n"); return 1; } else { *(p + 1) = 456; printf("Value of p[1]: %d\n", *(p + 1)); free(p); // 释放内存 } }

内存释放函数

在使用完动态分配的内存后,必须手动将其释放,否则会导致内存泄漏问题。C 语言提供了以下函数用于内存释放:

free()

Copy Code
void free(void *ptr);
  • 功能:释放已经分配的内存空间。
  • 参数:ptr 表示需要释放的内存指针。

例如:

cCopy Code
int *p = (int *)malloc(sizeof(int)); // 分配一个整型变量的大小 if (p == NULL) { printf("Memory allocation failed.\n"); return 1; } else { *p = 123; printf("Value of p: %d\n", *p); free(p); // 释放内存 }

实例

下面是一个动态分配二维数组并进行赋值的例子:

cCopy Code
int main() { int row = 3, col = 4; int **matrix = (int **)malloc(sizeof(int *) * row); // 分配包含 row 个指针的数组 if (matrix == NULL) { printf("Memory allocation failed.\n"); return 1; } else { for (int i = 0; i < row; i++) { *(matrix + i) = (int *)malloc(sizeof(int) * col); // 分配包含 col 个整型变量的数组 if (*(matrix + i) == NULL) { printf("Memory allocation failed.\n"); return 1; } else { for (int j = 0; j < col; j++) { *(*(matrix + i) + j) = i * j; // 对每个元素赋值 printf("%d ", *(*(matrix + i) + j)); } printf("\n"); } } for (int i = 0; i < row; i++) { free(*(matrix + i)); // 释放每行数组的空间 } free(matrix); // 释放指针数组的空间 } return 0; }

以上就是动态内存分配和释放的基本操作,程序员需要谨慎使用,避免出现内存泄漏和空指针访问等问题。