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;
}
相关文章
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
6天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
23 4
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
99 21
|
26天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
29天前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
36 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
1月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
66 1
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
153 1
|
1月前
|
存储 安全 程序员
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
63 3