💖💖⚡️⚡️专栏:C编程入门-轻松入门/系统总结⚡️⚡️💖💖
[C编程入门] 专为C语言初学者设计,提供轻松易懂的入门教程与系统的知识总结。本专栏将带你从零开始,循序渐进地掌握C语言的核心概念与编程技巧。无论你是完全没有编程背景的学生,还是希望系统学习C语言的自学者,这里都有丰富的示例和详尽的解释,帮助你打下坚实的编程基础,轻松迈入程序设计的世界。通过本专栏的学习,你将能够自信地运用C语言解决问题,并为进一步的技术提升铺平道路。
8.1 动态内存分配基础
动态内存分配是在程序运行时分配和释放内存的过程。
8.1.1 分配内存
// 分配内存
int *p = malloc(sizeof(int));
-
语法:
void *malloc(size_t size);
-
示例:
int *p = malloc(sizeof(int));
-
分配内存:
- 使用
malloc
函数分配内存。 - 参数是所需内存的大小,单位是字节。
malloc
函数返回一个指向分配内存的指针,如果分配失败,则返回NULL
。- 分配内存前需要检查是否成功,通常使用
if (p == NULL)
来检查。
- 使用
详细说明:
malloc
函数用于在堆上分配内存。- 参数
size
是所需内存的大小,单位是字节。 malloc
函数返回一个指向分配内存的指针,如果分配失败,则返回NULL
。- 分配内存时需要确保有足够的内存可用,否则可能导致程序崩溃。
- 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
malloc
函数分配的内存不保证被初始化,因此使用前需要显式初始化。
8.1.2 释放内存
// 释放内存
free(p);
-
语法:
void free(void *ptr);
-
示例:
free(p);
-
释放内存:
- 使用
free
函数释放之前分配的内存。 - 参数是之前通过
malloc
、calloc
或realloc
分配的内存指针。 - 释放内存后,不应再使用该指针指向的内存,以避免产生未定义的行为。
- 使用
详细说明:
free
函数用于释放之前通过malloc
、calloc
或realloc
分配的内存。- 参数
ptr
是指向要释放的内存的指针。 - 释放内存后,指针仍然有效,但不应再使用它指向的内存,因为这块内存可能已经被其他用途占用。
- 释放内存是重要的步骤,它可以防止内存泄漏,减少程序占用的资源。
- 在程序结束之前,所有动态分配的内存都应该被释放,以防止数据丢失或资源泄露。
8.1.3 初始化内存
// 初始化内存
int *q = calloc(10, sizeof(int));
-
语法:
void *calloc(size_t nmemb, size_t size);
-
示例:
int *q = calloc(10, sizeof(int));
-
初始化内存:
- 使用
calloc
函数分配并初始化内存。 - 第一个参数是要分配的元素数量。
- 第二个参数是每个元素的大小。
calloc
函数返回一个指向分配并初始化为零的内存的指针,如果分配失败,则返回NULL
。- 分配内存前需要检查是否成功,通常使用
if (q == NULL)
来检查。
- 使用
详细说明:
calloc
函数用于在堆上分配内存,并将分配的内存初始化为零。- 参数
nmemb
是要分配的元素数量,size
是每个元素的大小,单位是字节。 calloc
函数返回一个指向分配并初始化为零的内存的指针,如果分配失败,则返回NULL
。- 与
malloc
相比,calloc
除了分配内存外还会将内存初始化为零,这对于需要初始化内存的情况非常有用。 - 分配内存时需要确保有足够的内存可用,否则可能导致程序崩溃。
- 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
8.1.4 重新分配内存
// 重新分配内存
int *r = realloc(p, 20 * sizeof(int));
-
语法:
void *realloc(void *ptr, size_t size);
-
示例:
int *r = realloc(p, 20 * sizeof(int));
-
重新分配内存:
- 使用
realloc
函数重新分配内存。 - 第一个参数是指向之前分配的内存的指针。
- 第二个参数是新的内存大小。
realloc
函数返回一个指向新分配的内存的指针,如果分配失败,则返回NULL
。- 如果新的内存大小大于原来的大小,原有数据将被保留;如果新的内存大小小于原来的大小,多余的数据将被裁剪。
- 使用
详细说明:
realloc
函数用于更改之前分配的内存块的大小。- 参数
ptr
是指向之前分配的内存的指针,size
是新的内存大小,单位是字节。 realloc
函数返回一个指向新分配的内存的指针,如果分配失败,则返回NULL
。- 如果新的内存大小大于原来的大小,原有数据将被保留;如果新的内存大小小于原来的大小,多余的数据将被裁剪。
- 在使用
realloc
时,需要特别小心,确保正确处理返回的指针。 - 如果
realloc
返回NULL
,则表示分配失败,需要释放原来的内存并采取适当的措施。
8.2 动态内存管理示例
8.2.1 动态分配数组
动态分配一个整数数组,并对其进行初始化。
#include <stdio.h>
#include <stdlib.h>int main() {int *array;int n = 10;array = malloc(n * sizeof(int));if (array == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < n; i++) {array[i] = i + 1;}for (int i = 0; i < n; i++) {printf("%d ", array[i]);}printf("\n");free(array);return 0;
}
-
示例:
#include <stdio.h> #include <stdlib.h>int main() {int *array;int n = 10;array = malloc(n * sizeof(int));if (array == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < n; i++) {array[i] = i + 1;}for (int i = 0; i < n; i++) {printf("%d ", array[i]);}printf("\n");free(array);return 0; }
-
动态分配数组:
- 使用
malloc
函数分配一个整数数组。 - 使用
for
循环初始化数组。 - 使用另一个
for
循环打印数组。 - 使用
free
函数释放数组内存。
- 使用
详细说明:
- 本示例演示了如何动态分配一个整数数组,并对其进行初始化。
- 使用
malloc
函数分配一个整数数组。 - 使用
for
循环初始化数组,这里将数组元素设置为从1到10的整数。 - 使用另一个
for
循环打印数组。 - 使用
free
函数释放数组内存。 - 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
- 此示例展示了如何使用动态内存分配来创建和管理数组。
8.2.2 动态分配二维数组
动态分配一个二维整数数组,并对其进行初始化。
#include <stdio.h>
#include <stdlib.h>int main() {int **matrix;int rows = 3, cols = 4;matrix = malloc(rows * sizeof(int *));if (matrix == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < rows; i++) {matrix[i] = malloc(cols * sizeof(int));if (matrix[i] == NULL) {printf("Memory allocation failed.\n");return 1;}}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {matrix[i][j] = i * cols + j + 1;}}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", matrix[i][j]);}printf("\n");}for (int i = 0; i < rows; i++) {free(matrix[i]);}free(matrix);return 0;
}
-
示例:
#include <stdio.h> #include <stdlib.h>int main() {int **matrix;int rows = 3, cols = 4;matrix = malloc(rows * sizeof(int *));if (matrix == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < rows; i++) {matrix[i] = malloc(cols * sizeof(int));if (matrix[i] == NULL) {printf("Memory allocation failed.\n");return 1;}}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {matrix[i][j] = i * cols + j + 1;}}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", matrix[i][j]);}printf("\n");}for (int i = 0; i < rows; i++) {free(matrix[i]);}free(matrix);return 0; }
-
动态分配二维数组:
- 使用
malloc
函数分配一个指针数组,用于存放每行的指针。 - 使用嵌套的
malloc
函数为每一行分配内存。 - 使用嵌套的
for
循环初始化二维数组。 - 使用嵌套的
for
循环打印二维数组。 - 使用嵌套的
free
函数释放二维数组的内存。
- 使用
详细说明:
- 本示例演示了如何动态分配一个二维整数数组,并对其进行初始化。
- 使用
malloc
函数分配一个指针数组,用于存放每行的指针。 - 使用嵌套的
malloc
函数为每一行分配内存。 - 使用嵌套的
for
循环初始化二维数组,这里将数组元素设置为从1到12的整数。 - 使用嵌套的
for
循环打印二维数组。 - 使用嵌套的
free
函数释放二维数组的内存。 - 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
- 此示例展示了如何使用动态内存分配来创建和管理二维数组。
8.3 实践练习
8.3.1 练习动态分配字符串
编写一个程序,动态分配一个字符串,并从用户输入中读取内容。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {char *str;int len;printf("Enter the length of the string: ");scanf("%d", &len);str = malloc((len + 1) * sizeof(char));if (str == NULL) {printf("Memory allocation failed.\n");return 1;}printf("Enter the string: ");scanf("%s", str);printf("String: %s\n", str);free(str);return 0;
}
-
示例:
#include <stdio.h> #include <stdlib.h> #include <string.h>int main() {char *str;int len;printf("Enter the length of the string: ");scanf("%d", &len);str = malloc((len + 1) * sizeof(char));if (str == NULL) {printf("Memory allocation failed.\n");return 1;}printf("Enter the string: ");scanf("%s", str);printf("String: %s\n", str);free(str);return 0; }
-
动态分配字符串:
- 使用
malloc
函数分配字符串内存。 - 使用
scanf
函数从用户输入中读取字符串。 - 使用
printf
函数打印字符串。 - 使用
free
函数释放字符串内存。
- 使用
详细说明:
- 本练习要求编写一个程序,动态分配一个字符串,并从用户输入中读取内容。
- 使用
malloc
函数分配字符串内存。 - 使用
scanf
函数从用户输入中读取字符串。 - 使用
printf
函数打印字符串。 - 使用
free
函数释放字符串内存。 - 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
- 此练习展示了如何使用动态内存分配来创建和管理字符串。
8.3.2 练习动态分配多维数组
编写一个程序,动态分配一个多维数组,并对其进行初始化。
#include <stdio.h>
#include <stdlib.h>int main() {int ***matrix;int dim1 = 2, dim2 = 3, dim3 = 4;matrix = malloc(dim1 * sizeof(int **));if (matrix == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < dim1; i++) {matrix[i] = malloc(dim2 * sizeof(int *));if (matrix[i] == NULL) {printf("Memory allocation failed.\n");return 1;}for (int j = 0; j < dim2; j++) {matrix[i][j] = malloc(dim3 * sizeof(int));if (matrix[i][j] == NULL) {printf("Memory allocation failed.\n");return 1;}}}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {for (int k = 0; k < dim3; k++) {matrix[i][j][k] = i * dim2 * dim3 + j * dim3 + k + 1;}}}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {for (int k = 0; k < dim3; k++) {printf("%d ", matrix[i][j][k]);}printf("\n");}printf("\n");}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {free(matrix[i][j]);}free(matrix[i]);}free(matrix);return 0;
}
-
示例:
#include <stdio.h> #include <stdlib.h>int main() {int ***matrix;int dim1 = 2, dim2 = 3, dim3 = 4;matrix = malloc(dim1 * sizeof(int **));if (matrix == NULL) {printf("Memory allocation failed.\n");return 1;}for (int i = 0; i < dim1; i++) {matrix[i] = malloc(dim2 * sizeof(int *));if (matrix[i] == NULL) {printf("Memory allocation failed.\n");return 1;}for (int j = 0; j < dim2; j++) {matrix[i][j] = malloc(dim3 * sizeof(int));if (matrix[i][j] == NULL) {printf("Memory allocation failed.\n");return 1;}}}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {for (int k = 0; k < dim3; k++) {matrix[i][j][k] = i * dim2 * dim3 + j * dim3 + k + 1;}}}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {for (int k = 0; k < dim3; k++) {printf("%d ", matrix[i][j][k]);}printf("\n");}printf("\n");}for (int i = 0; i < dim1; i++) {for (int j = 0; j < dim2; j++) {free(matrix[i][j]);}free(matrix[i]);}free(matrix);return 0; }
-
动态分配多维数组:
- 使用嵌套的
malloc
函数为多维数组分配内存。 - 使用嵌套的
for
循环初始化多维数组。 - 使用嵌套的
for
循环打印多维数组。 - 使用嵌套的
free
函数释放多维数组的内存。
- 使用嵌套的
详细说明:
- 本练习要求编写一个程序,动态分配一个多维数组,并对其进行初始化。
- 使用嵌套的
malloc
函数为多维数组分配内存。 - 使用嵌套的
for
循环初始化多维数组,这里将数组元素设置为从1到24的整数。 - 使用嵌套的
for
循环打印多维数组。 - 使用嵌套的
free
函数释放多维数组的内存。 - 在实际应用中,经常需要在分配内存之前进行错误检查,以确保后续的操作能够正常进行。
- 此练习展示了如何使用动态内存分配来创建和管理多维数组。
8.4 小结
本章介绍了C语言中的动态内存管理。通过这些知识,你可以创建程序来动态地分配和释放内存。接下来,你可以继续深入到更复杂的主题,如信号处理、多线程编程等。