C++ 动态内存

本节我们主要了解C++的动态内存的申请和使用方式。

首先了解一下内存的几种形式

首先是栈

就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。和堆一样,用户栈在程序执行期间可以动态地扩展和收缩。

全局/静态存储区

全局/静态存储区,存放的是全局变量和静态变量。该存储区在整个程序运行期间一直有效,直到程序结束,系统才回收。                         

常量存储区

这个区存储的是常量,通常不允许修改。 # define

自由存储区

就是那些由 malloc 等分配的内存块,他和堆是十分相似的,不过它是用 free 来结束自己的生命的。

那些由 new 分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个 new 就要对应一个 delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。堆可以动态地扩展和收缩。

它与其它变量相比的最大好处

1.相对于栈它可以在多个程序中被访问,栈的最大内存应该是1M,堆的是4G。

但是堆申请和释放的比较多的话可能存在垃圾(内存不连续影响程序执行速率),栈就不会有这个问题,栈的内存释放是先进后出

2.相对于全局变量,它的大小可以改变和定义,它所占用的空间也可以被释放。

动态内存 堆的申请方式

void f() { int* p=new int[5]; }

可以看到我们在函数中申请了大小为5个int的堆内存,在申请堆内存之前我们首先为*p申请了栈空间,之后在程序会先确定在堆中分配内存的大小,然后调用 operator new 分配内存,然后返回这块内存的首地址,放入栈中。

int foo(int x)
{
    int y = x * 2;
    int *p = new int[5];
    p[0] = y;
}

在以上代码中如果我们调用后,x和y内存都会自动释放,但是p所指向的数组不会释放,如果我们想删除该内存就必须加上delet[] p;

若果我们不写delete这个函数就无人问津了,因为知道这个内存地址的p已经消失了。但是内存还在被占用这,其它程序无法使用,这个就是内存泄漏。

int foo(int x)
{
    int y = x * 2;
    int* p = new int[5];
    p[0] = y;
    delete[] p;
}

有时我们会使用nullptr来将p变为空指针。

#include <iostream>
using namespace std;
int main()
{
int *p = new int;

delete p;

p = nullptr;

if(p!=nullptr)
{
  cout<<"p!=nullptr"<<endl;
}
else if(p==nullptr)
{
  cout<<"p==nullptr"<<endl;
}

}

nullptr有时可以使用 NULL进行代替,但是在C++11之前有的NULL和int可能会搞混。

这是基本的申请和释放方式,在实际使用时,我们的堆可能在一个函数中申请但是在多个函数中使用,这时我们需要注意其释放位置,或者可以通过智能指针解决这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值