C++(二)内存管理

简介: 本文档详细介绍了C++中的内存管理机制,特别是`new`和`delete`关键字的使用方法。首先通过示例代码展示了如何使用`new`和`delete`进行单个变量和数组的内存分配与释放。接着讨论了内存申请失败时的处理方式,包括直接抛出异常、使用`try/catch`捕获异常、设置`set_new_handler`函数以及不抛出异常的处理方式。通过这些方法,可以有效避免内存泄漏和多重释放的问题。

c 语言中提供了 malloc 和 free 两个系统函数,完成对堆内存的申请和释放。而 c++则
提供了两关键字 new 和 delete ;

new/delete

new/new[]用法:

int *p = new int; //开辟大小为 sizeof(int)空间

int *a = new int(5); //开辟大小为 sizeof(int)空间,并初始化为 5

// todo new/delete

#include <iostream> //<iostream>
using namespace std; //
int main() {

    //单变量
    int *p=new int(20);
    cout<<*p<<endl; //20
    *p=10;
    cout<<*p<<endl; //10

    string *s=new string("hello");
    cout<<*s<<endl; //hello
    *s="world";
    cout<<*s<<endl; //world


    struct Sut{
        int age;
        string name;
    };
    Sut* s1=new Sut;
    s1->age=20;
    s1->name="Tom";
    cout<<s1->age<<endl; //20
    cout<<s1->name<<endl; //Tom


    Sut* s2=new Sut{10,"Jerry"};
    cout<<s2->age<<endl; //10
    cout<<s2->name<<endl; //Jerry

    delete s2;
    delete s1;
    delete p;
    delete s;
    return 0;
}

多变量空间:


int main() {
     //多变量
     //一维数组
     char* p= new char[40]; //分配40个字节的内存
     memset(p,0,40); //将内存块全部初始化为0
     strcpy(p,"hello world");
     cout<<p<<endl;//hello world

     int *pi=new int[5]{0};//分配5个int类型的内存,并初始化为0
     pi[0]=10;
     for(int i=0;i<5;i++){
         cout<<pi[i]<<" "; //10 0 0 0 0
     }

    char **ppc=new char *[5]{NULL};
    ppc[0]="qqq";
    ppc[1]="www";
    ppc[2]="eee";

    ppc[3]=new char[10];
    strcpy(ppc[3],"xxxxx");
    cout<<endl;

    while(*ppc) {
        cout<<*ppc++<<" "; //qqq www eee xxxxx
    }
    cout<<endl;

    //多维数组
    int (*q)[3] = new int[2][3];
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<3; j++)
        {
            q[i][j] = i+j;
        }
    }
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<3; j++)
        {
            cout<<q[i][j]<<" ";
        }
        cout<<endl;
    }

    int (*qq)[3][4] = new int [2][3][4];


    delete[] qq; //释放内存
    delete[] q; //释放内存
    delete[] ppc[3]; //释放内存
    delete[] ppc; //释放内存
    delete[] pi; //释放内存
    delete[] p; //释放内存
}

new/delete 是关键字,效率高于 malloc 和 free.

配对使用,避免内存泄漏和多重释放。

避免,交叉使用。比如 malloc 申请的空间去 delete,new 出的空间被 free;

new/delete 关键字,重点用在类对像的申请与释放。申请的时候会调用构造器完成初始化,释
放的时候,会调用析构器完成内存的清理。

返回值判断

内存申请失败

int main()
{
    double * pd[50];
    for(int i=0; i<50; i++)
    {
        pd[i] = new double[50000000];
        cout<<i<<endl;
    }
return 0;
}

直接抛出异常,结束程序:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

try/catch 捕获异常


int main()
{
    double * pd[50];

    try {
        for(int i=0; i<50; i++)
        {
            pd[i] = new double[50000000];

            cout<<i<<endl;
        }
    }catch (std::bad_alloc & e){
        cout<<"内存分配失败: "<<e.what()<<endl;
    }

    cout<<"程序结束"<<endl;



    return 0;
}
内存分配失败: std::bad_alloc
程序结束

set_new_handler


void newErr()
{
    cout<<"new error"<<endl;
    exit(-1);
}

int main()
{
    double * pd[50];
    //set_new_handler 是用来设置一个新的内存分配函数的,当内存分配失败时,会调用这个函数。
    set_new_handler(newErr);

    for(int i=0; i<50; i++)
    {
        pd[i] = new double[50000000];

        cout<<i<<endl;
    }

    cout<<"程序结束"<<endl;



    return 0;
}

输出:
new error

不会抛出异常处理方式

int main()
{
    double * pd[50];
    //set_new_handler 是用来设置一个新的内存分配函数的,当内存分配失败时,会调用这个函数。
    //set_new_handler(newErr);

    for(int i=0; i<50; i++)
    {
        //(nothrow)设置异常处理,如果内存分配失败,不会抛出异常,而是返回nullptr
        pd[i] = new (nothrow)double[50000000];
        if(pd[i] == nullptr){
            cout<<"分配内存失败:"<<__FILE__<<" "<<__func__ <<" "<<__LINE__<<endl;
            exit(-1);
        }

    }
    cout<<"程序结束"<<endl;
    return 0;
}
相关文章
|
13天前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
32 2
|
2月前
|
存储 编译器 C语言
内存管理【C++】
内存管理【C++】
44 1
|
2月前
|
存储 编译器 C语言
【C++】C\C++内存管理
【C++】C\C++内存管理
【C++】C\C++内存管理
|
9天前
|
安全 C++
超级好用的C++实用库之环形内存池
超级好用的C++实用库之环形内存池
29 5
|
9天前
|
C++
超级好用的C++实用库之动态内存池
超级好用的C++实用库之动态内存池
19 0
|
2月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
2月前
|
存储 Java C语言
【C++】C/C++内存管理
【C++】C/C++内存管理
|
2月前
|
存储 编译器 C语言
C++内存管理(区别C语言)深度对比
C++内存管理(区别C语言)深度对比
72 5
|
2月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
40 0
|
3月前
|
NoSQL Redis C++
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难