学习c艹过程中学习了指针我们就提了一下动态内存(不知道其他学校是怎么样的),老师讲了一下也没能理解透彻,看了几篇博客有了以下理解,望大佬批评指正:
像我们开始的一般变量定义,形如:
int a=0; //定义了一个等于10的整型变量(4个byte)
char a[10]={0}; //定义了一个初始值为0的数组(1*10个byte)
它们都是在在栈内申请的空间,你是知道你要做一件什么事,知道你要申请空间的大小,再去申请的,我们称之为静态内存开辟。但实际coding时,有很多情况你是不知道需要空间大小的,只有程序运行过程中才知道,此时,静态内存开辟已经无法满足我们的需求了,所以有了我们的动态内存。
下面我们来看两个申请动态空间的常用函数(老师课上提到的,其他要后面慢慢解锁了,呜呜呜)。
-
malloc与free函数(c语言)
-
malloc()申请动态内存。
-
free()释放动态内存。
-
都在stdlib.h头文件里。
首先是malloc函数:
void * malloc(unsigned size); //malloc函数原型
举个栗子~:
int * p=(int*)malloc(sizeof(int)); //按照int类型数据存储空间的大小分配内存空间
由malloc函数申请size个byte的空间,然后返回指向这块空间的指针(void*类型),但是如果申请不到空间就返回NULL,如例子中的p就指向申请的内存空间;*p访问该空间。
然后是常和malloc一起用的free函数:
void free(void * ptr); //free函数原型
举栗子again~:
free(p); //释放p指向的内存
p=NULL; //p指向的内存已释放,但p的值还存在,为其赋值0后,可以避免使用它来访问无效内存
free函数可以释放先前malloc所分配的内存,所要释放的内存由指针ptr指向。
我们可以尝试着coding一下了:
//在堆内存中申请空间放大的数组
#include<iostream>
#include<ctime>
#include<stdlib.h>
using namespace std;
int main(){
const int N=5201314;
int *p=(int*)malloc(sizeof(int)*N);
srand(time(NULL));
int *str=p;
for(int i=0;i<10;i++){
*str=rand()%100;
str++;
}
for(int i=0;i<20;i++){
cout<<*(p+i)<<endl;
}
free(p);
return 0;
}
-
new与delete函数(c艹)
-
new申请动态内存。
-
delete释放动态内存。
-
new与delete都是运算符。
先是new:
new <类型名> (初值);//一般使用格式,数组的话会有点不一样
或者
new <类型名> [表达式];//申请动态一维数组使用格式,表达式就像是例子“在堆内存中申请空间放大的数组”中的N
还是一样的,如果申请成功,返回指定类型内存的地址;如果申请失败,返回NULL指针。
继续举栗子:
p=new int(10);//申请10个byte的动态空间
接下来是delete:
delete <指针名>;//一般使用格式,对数组有些差异
或者
delete [ ]<指针名>;//释放动态一维数组空间使用格式
栗子举高高~:
delete p;//释放p指向内存
p=NULL;//同free()一样的道理
基本的道理和malloc以及free一样,我们直接coding!
用同样的题目:
//在堆内存中申请空间放大的数组
#include<iostream>
#include<ctime>
using namespace std;
int main(){
const int N=5201314;
int *p=new int[N];//注意对数组是[]不是(),本人就犯蠢了,还找不到哪里出问题了,呜呜呜
srand(time(NULL));
int *str=p;
for(int i=0; i<10; i++){
*str=rand()%100;
str++;
}
for (int i=0; i<20; i++){
cout<<*(p+i)<<endl;
}
delete[]p;
return 0;
}
除此之外,注意动态空间开辟了多少,避免发生越界的情况,且new与delete也好,malloc()和free()也好,必须一对一对用,光释放或者光申请不释放都是有问题的,new与delete使用格式那里也需要多加注意(已受教训,呜呜呜),其次,不能多重释放(连着释放),否则在第一次释放后,原本的指针就变为野指针了,再次释放,释放野指针,程序会崩溃的。