C语言 内存管理
C语言 内存管理
堆区内存分配和释放
一、malloc 函数
#include <stdlib.h> void *malloc(size_t size);
功能:在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。分配的内存空间内容不确定,一般使用memset初始化。
参数:
- size:需要分配内存大小(单位:字节)
返回值:
- 成功:分配空间的起始地址
- 失败:NULL
二、free 函数
#include <stdlib.h> void free(void *ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,指向被释放区域的首地址。对同一内存空间多次释放会出错。
参数:
- ptr:需要释放空间的首地址,被释放区应是由malloc函数所分配的区域。
返回值:无
三、案例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> int main(void) { // 栈区大小 1M //int arr[210000] = {0}; // 1、开辟堆空间存储数据 // int* p (强制转换的类型*)malloc(sizeof(开辟类型大小)); int* p = (int*)malloc(sizeof(int)); // 2、使用堆空间 *p = 123; printf("%d\n", *p); // 3、释放堆空间 free(p); // 避免野指针出现 // p = NULL; // 查看内存地址、p为野指针 printf("%p\n", p); // 操作野指针、释放后再次使用堆空间 *p = 123; printf("%d\n", *p); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> int main(void) { // 开辟堆内存空间 int* p = (int*)malloc(sizeof(int) * 10); // 判断p内存是否开辟成功 if (!p) { printf("程序异常"); return -1; } // 通过指针存储操作堆空间 for (int i = 0; i < 10; i++) { p[i] = i; } // 输出堆空间内容 for (int i = 0; i < 10; i++) { printf("%d\n", *(p + i)); } // 释放内存 free(p); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> #define MAX 10 int main(void) { // 通过堆内存、创建随机数 srand((size_t)time(NULL)); // 如果指针改变该堆内存则变为无主空间 int* p = (int*)malloc(sizeof(int) * MAX); for (size_t i = 0; i < MAX; i++) { p[i] = rand() % 100; printf("%d\n", p[i]); } for (size_t i = 0; i < MAX; i++) { printf("%d\n", p[i]); // p++; } // 如p++改变指针地址free则无法释放内存 free(p); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> int main(void) { // 二级指针开放堆空间存储一级指针的内存地址 // int arr[5][3] int** p = (int**)malloc(sizeof(int*) * 5); // 开辟一级指针对应的堆空间 for (int i = 0; i < 5; i++) { // 通过二级指针、开辟一级指针对应堆空间 p[i] = (int*)malloc(sizeof(int) * 3); } // 赋值 for (int i = 0; i < 5; i++) { for (int j = 0; j < 3; j++) { scanf("%d", &p[i][j]); } } // 打印 for (int i = 0; i < 5; i++) { for (int j = 0; j < 3; j++) { // printf("%d", p[i][j]); // printf("%d", *(p[i]+j)); printf("%d", *(*(p+i)+j)); } printf("\n"); } for (int i = 0; i < 5; i++) { // 释放一级指针堆空间 free(p[i]); } // 释放二级指针堆空间 free(p); return 0; }