C的动态内存申请
本篇适合有一定C/C++基础的同学
在C语言中,我们自己来申请一块内存需要用到头文件<stdlib.h>或<malloc.h>:
#include <stdlib.h>
#include <malloc.h>
malloc.h是包含在stdlib.h中的:
主要用到其中的malloc函数,使用时需要强制类型转换,给什么类型的变量申请内存就要转换成对应的指针类型(因为程序需要告诉编译器malloc函数返回值的第一个字节是int *类型的还是其他类型的。),例如申请一段int类型的内存:
int* pNum = (int*)malloc(sizeof(int) * 5);
// 为pNum申请5个连续的内存地址,乘几就表示申请几个
// sizeof(int)表示每个内存地址的大小是一个int型变量占的字节数
其实就相当于声明了一个长度为5的整型数组:
int pNum[5];
这种申请方式并没有初始化数据(同学们最好都要养成在定义变量的时候就给它初始化的习惯),calloc函数可以自动给申请的内存初始化值,初始化的值都是对应类型的0值,int就是0,char就是'\0',等等。但是它要传入两个参数:
int* pNum = (int*)calloc(sizeof(int), 5);
第一个参数就是申请的每个内存地址的大小,第二个是申请多少个内存地址。可以看出其实就是把malloc函数的参数拆开写了:sizeof(int) * 5 写成了 sizeof(int) 和 5。
区别就是初始化:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i = 0;
// calloc申请一段内存,申请5个int占用字节数大小的内存
int* pNum = (int*)calloc(sizeof(int), 5); // 每个内存自动初始化为0
for(i = 0; i < 5; i++){
printf("%d ", pNum[i]);
}
return 0;
}
运行结果:
可以看到都初始化为0了。然而用malloc的话,打印的全是垃圾值:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i = 0;
int* pNum = (int*)malloc(sizeof(int) * 5);
for(i = 0; i < 5; i++){
printf("%d ", pNum[i]);
}
return 0;
}
但我们可以自己给pNum初始化:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i = 0;
int* pNum = (int*)malloc(sizeof(int) * 5);
for(i = 0; i < 5; i++){
pNum[i] = i;
}
for(i = 0; i < 5; i++){
printf("%d ", pNum[i]);
}
return 0;
}
那如何申请二维数组的内存的内存呢?
int i = 0;
// 申请了一个3行的二维数组的内存
int** ppNum = (int**)malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++){
// 为每一行申请长度为4的内存地址
ppNum[i] = (int*)malloc(sizeof(int) * 4);
}
其实就相当于声明一个3行4列的二维数组:
int ppNum[3][4];
然后就可以对该数组里面每个元素进行赋值等操作了。
申请的内存不用的时候要及时释放掉,虽然我们平时自己写的一些小程序无所谓,但是一个超大的项目,一个大型游戏,不把不用的内存释放掉它是会占CPU资源的,造成内存泄漏,所以大家都要养成这个习惯。(如果你电脑配置极高当我没说)☻
释放内存用malloc.h中的free函数:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i = 0;
// 申请长度为5的内存地址,整型
int* pNum = (int*)malloc(sizeof(int) * 5);
// 申请了一个3行的二维数组的内存
int** ppNum = (int**)malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++){
// 为每一行申请长度为4的内存地址
ppNum[i] = (int*)malloc(sizeof(int) * 4);
}
free(pNum); // 释放pNum的内存
pNum = NULL; // 置空pNum的指向
for(i = 0; i < 5; i++){
free(ppNum[i]); // 释放ppNum的每一行的内存
ppNum[i] = NULL; // 置空ppNum的每一行的指向
}
free(ppNum); // 释放ppNum的内存
ppNum = NULL; // 置空ppNum的指向
return 0;
}
释放内存从低维到高维,一维的直接free(指针名)就行了,二维的先把每一行释放掉free(指针名[i]),再free(指针名)即可,三维,四维...类推即可。而且释放掉的内存,本来指向它的指针要指向空,即置空,没有指向的指针我们一般称为野指针,大家在写代码的时候尽量不要出现野指针,原因嘛,我们老师说会被人觉得没有素养(但我就是经常忘记)。
下一篇,我们开始自己写函数来申请内存。希望大家多多指正多多支持噢。😀😄