c++和c语言动态内存分配

2024-01-01 06:52:13

动态开辟内存,就是在堆区,可以根据自己的需要开辟和释放。(用完一定得释放)?

1.C语言

malloc和free?

1. (void*)malloc(size_t n);? // 传入一个需要开辟多少个字节的内存?(可以是一个常数,也可以是一个可以计算出的表达式),返回一个void*指针指向开辟内存的首地址。根据你存放数据的类型将返回指针强行转换成相应内存即可。

? ?要使用此函数得导入<stdlib.h>头文件使用此函数的开辟的内存,使用free()函数释放

int *a  = (int*)malloc(1024);//开辟1024个字节
free(a);
a = NULL;

上面代码,开辟了1kb的内存,存放int数据,所以要将其返回的void*指针强制转换为int*,返回赋值给指针a。试用结束,用free()释放这片内存。?

因为,我们释放了内存之后,但是指针a还存在,因为它指向的内存已经释放,我们是万万不能再去访问它,所以为了保险起见,释放完内存之后,将它指向NULL;?

2.c++?

?new和delete

c++中动态开辟内存使用new运算符。

int* test; // 定义一个指针,可以指向一片空间
int (*test1)[5]; // 定义一个指向二维数组的指针


test = new int;   //使用new申请一个int空间 
test = new int(10);  // 使用new开辟一个int空间并且初始化为10

delete test; // 释放内存直接使用delete

int nub = 10;
test = new int[nub];  // 使用new申请nub个int类型的连续空间
test1 = new int[nub][5]; // 使用new申请一个nub行5列的二维数组。
                         // 必须是使用一个指向二维数组的指针才可以,所以使用test是不行的
                         // 只有第一个[]可以使用变量及相关表达式。第二个[]只能使用常量和常量表达 
                           式

//使用下面形式释放一片空间([]号中不需要写多少,因为os有标记)
delete[] test;
delete[] test1; 

// 注意:在使用delete释放申请到的内存时,必须使用我们用于指向这片内存(首地址),也就是我们申请内存
// 时,用于指向这片内存的指针,--在本例中为:test和test1,不可以是test+1等。

上面的代码就使用了new和delete运算符来实现动态内存分配的。??

?

3. delete和free可以交替使用?

意思是,使用malloc函数申请的内存可以通过delete释放。?

? ? ? ? ? ? 使用new运算符申请的内存可以通过free释放。?

int *m_pointer = (int *)malloc(1024); // 申请1kb

delete[] m_pointer;  // 使用delete释放


int *n_pointer = new int; // 申请4个字节

free(n_pointer); // 使用free释放

?

4. mallloc,free和new,delete的对比(在c++中建议使用后者)?

因为,malloc和free都是函数,有调用上的开销。而c++中new和delete是运算符,所以new和delete的效率要高于malloc和free,所以我们平时在c++中建议使用后者。?

因为c++完全兼容C语言,所以也可以使用malloc和free来实现。?

?

5. 使用动态分配内存的好处?

好处一:? 我们可以根据自己的需要来积极申请内存,可以减少一定的内存损耗。?

比如:我们平时需要输入一组数据,因为我们最开始不知道这组数据的数量,之前我们可以定义一个数组来存储,但是数组不支持变量定义和动态变化-----所以我们只能将数组定义的尽可能的大一点。?

int a[1024];? ?当我们定义一个这样的数组时,我们可能只需要放十个数据在里面,这样就浪费了很多空间。?

使用动态分配存储的内存就可以降低这种的损耗。?

?

好处二:可以使程序有更多可以使用的内存。?

我们平时写程序时,一些局部变量等在栈中存储,但是栈内存是有限的,windows可能是1M-2M(因为要给别的程序预留),而如果我们想要创建使用很大一片内存,这时候,就可以从堆中使用, 堆的空间1G-2G一般。?

?

好处三:我们可以自己控制它的生命周期--使得到其他函数中的内容成为可能。?

1. 堆区内存的生命周期? ----? ?从申请成功开始到释放。(这个过程是我们可以控制的)?。

2. 因为我们平时使用函数返回一个指针(变量地址)时,往往是不可以返回局部变量的,因为函数调用结束之后该变量对应的内存就被回收了,你再去访问那不就出问题了。?

如果想要返回函数内的创建的内存: 1. 使用static定义变量? ? 2. 使用动态开辟的内存(未释放的)?

6. 使用动态内存分配的风险 -- 内存泄漏?

内存泄漏:? ? 我们申请了内存,但是我们不使用,os也不知道,这其实就是内存泄漏。?

我们动态申请的内存使用完一定要释放掉,如果不释放,你不使用它,os又不知道,你再次去申请内存,一直不释放,就会导致很多空间浪费了,可使用的内存也会逐渐降,直到程序崩溃。?

文章来源:https://blog.csdn.net/weixin_68026222/article/details/135315034
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。