C语言中手把手教你动态内存分配,快来get新知识

动态内存管理

非静态的局部变量是分配在内存中的动态存储区,这个存储区是一个称为 栈 的区域

如:int a 存放在栈区

C语言还允许建立动态分配区域,以存放一些临时用的数据,这些数据需要随时开辟,不需要的时候试试释放,这些数据是临时存放在一个特别

的自由存储区,成为 堆 区

如:全局变量内存管理的手动分配单元 静态变量都是存在 堆区

关于静态和动态

静态内存分配是在程序执行之前进行的,因而效率比较高,但是它缺少灵活性,要求在程序执行之前,就知道所需要的内存的类型和数量

静态对象是有名字的变量,我们直接对起进行操作,而动态的对象是没有名字的变量,我们通过指针间接的对他进行操作

静态对象由编译器自动释放处理,动态变量需要手工释放

方法:

malloc

calloc

free

realloc

1、malloc(大小) 分配到堆区

void*malloc(usingned int size);单位是(byte)字节数

其作用是在内容的动态存储区分配一个长度位 side 空间,此函数是一个指针型函数,返回的指针是该分配区域的开头的位置(或首地址)

注意指针的类型位void 即不指向任何类型的数据,只提供一个地址。放什么类型的数据,强制转换位什么类型。

如果函数未能成功申请到空间(内存不足),返回空指针 NULL

如:

//分配40个字节的连续空间,让a指向新空间的首地址

int *a =(int*)malloc(40);

//判读是否申请成功

if(a == NULL){

}

练习:申请两个Student类型的空间

struct Student stu;

*p = (struct *Student) malloc(sizeof(struct Strdent)*2);

//判断

if(p==NULL){

}

另一种:使用typedef

typedef struct Student{

…..

……

}stu;

stu *p = (stu*) malloc( sizeof(stu)*2 );

//判断

if(p==NULL){

}

2、 calloc(数量,大小) 分配到堆区

viid * calloc(unsigned n,unsigned size); 上例改为 int a = sizeof(stu); stu *b = (stu*) calloc(2,a);

其作用是在内存的动态存储区中分配n个长度位 size的连续空间,这个空间一般比较大,足以保存一个数组

可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度位size,这就是动态数组。

calloc ----->malloc

如:calloc(m,n) ---->malloc(m*n);

malloc ----->calloc

如:malloc(a) ---->calloc(1,a);

例如:int *a = (int*)calloc(10,sizeof(int)); if(a==NULL) 40个字节,等于分配长度为 10 的一维数组


关于怎么快速学C/C++,可以加下小编的C/C++学习群:341+636+727,不管你是小白还是大牛,小编我都欢迎,不定期分享干货,欢迎初学和进阶中的小伙伴。


每天晚上20:00都会开直播给大家分享C/C++游戏编程学习知识和路线方法,群里会不定期更新最新的教程和学习方法,最后祝所有程序员都能够走上人生巅峰,让代码将梦想照进现实

3、free(指针变量)

void free(void *p); p=NULL;

其作用是释放指针变量p所指向的动态空间,这部分空间能重新被其他变量使用,p应是最近一次调用calloc或malloc函数时得到的函数返回值

free(p)释放指针变量p所指向的已分配的动态空间,但是注意,当p被释放后,p变为野指针,所以一定要加一句 p=NULL或p=0;

free函数无返回值

动态分配的空间用完后,必须要释放。

***** 注意 *****

在使用malloc或者cmalloc申请空间时,如 int *p = (int*)malloc(40);

p指针不允许进行 ++p 或者 --p,这样将导致 部分内存区域无法归还,导致内存泄露。

4、realloc(指针,大小)

void *realloc(void*p,unsigned int size);

如果已经通过malloc函数获取到了动态的空间,想改变大小,可以使用relloc函数重新分配

用realloc函数讲p所指向动态空间的大小改为size,p的值不变,如果重新分配不成功,返回NULL( "p=(int*)relloc(p,20)" 这句话有问题,一旦重新分配不成功,p=NULL,将会导致p指向的原来的空间也无法找到,无法归还,将导致内存泄露);

5、常见的内存错误:

使用未分配成功的内存

避免方式:在使用内存之前检查指针是否为NULL;

引用分配成功但尚未初始化的内存

避免方式:赋予初值,即便是赋予零值也不可省略

内存分配成功并且已经初始化,但操作越过了内存的边界

避免:注意下表的使用不能超出边界

忘记释放内存,造成内存泄露

避免方式:申请内存的方式和释放内存的方式需要成双成对

释放内存之后却继续去使用这一块内存

避免方式:使用free内存之后,把指针置为NULL;

内存错误的注意点:

指针消亡了,并不表示它所指向的内存会被自动释放,(在free之前,直接将指针设为NULL);

内存释放了,并不代表指针会消亡或者成了NULL指针;(在free之后,指针并没有进行NULL设置)

野指针:

野指针的形成是指针变量没有被初始化,任何指针变量刚被创建的时候不会自动成为NULL指针,它的缺省值是最忌的,它会乱指一气

指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法内存

free内存块之后,需要将指针设置为NULL,如果没有设置为NULL,也会出现“野指针”,它是指向“垃圾”内存的指针;

多次free内存块,是会导致程序崩溃的

猜你喜欢

转载自blog.csdn.net/chengxuyuan997/article/details/80838912