C++ 中,动态内存分配和释放是通过 new 和 delete 操作符来实现的。与C语言中的malloc和free类似,但具有更高级的功能和更好的类型安全性。动态内存分配可以在程序运行时根据需求分配内存,而不需要在编译时确定大小。与静态内存分配(在编译时分配)不同,动态内存分配提供了更大的灵活性,可以根据程序的实际需求来分配内存。本文主要介绍C++ 动态内存分配(new,delete)。

1、new 和 delete 运算符

:在函数内部声明的所有变量都将占用栈内存。

:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

newdelete是C++中的关键字,也是一种特殊的运算符。C++中如果要在堆内存中创建和销毁对象需要借助关键字newdelete来完成。

例如,

#include <iostream>
using namespace std;
class MyClass
{
    public:
       MyClass():i(0){}
       MyClass(int a):i(a){}
       virtual void foo(){ cout<<i<<endl;}
       int i;
};
void main()
{
       MyClass *p1 = new MyClass;
       MyClass *p2 = new MyClass(10);
       MyClass *p3 = new MyClass[20];
       delete p1;
       delete p2;
       delete[] p3;
}

注意:

1)C++中通过new关键字进行动态内存申请

2)C++中的动态内存分配是基于类型进行的

3)delete关键字用于内存释放

2、new关键字与malloc函数的区别

new 关键字和 malloc 函数都可以用于动态内存分配,但它们在功能、用途和行为上有显著的区别。

#include <iostream>
#include <exception>
using namespace std;

class MyClass {
public:
    int value;
    MyClass() { 
        value = 0; 
        cout << "Constructor called!" << endl; 
    }
    ~MyClass() { 
        cout << "Destructor called!" << endl; 
    }
};

int main() {
    // 使用 new 关键字分配内存
    MyClass* obj1 = new MyClass();
    obj1->value = 42;
    cout << "Value using new: " 
    << obj1->value << endl;
    delete obj1;  // 自动调用析构函数

    // 使用 malloc 函数分配内存
    MyClass* obj2 = (MyClass*)malloc(sizeof(MyClass));
    memset(obj2, 0, sizeof(MyClass));  // 初始化内存
    obj2->value = 42;
    cout << "Value using malloc: " 
    << obj2->value << endl;
    free(obj2);  // 不调用析构函数

    return 0;
}

1)new关键字是C++的一部分,malloc是由C库提供的函数。

2)new以具体类型为单位进行内存分配,malloc以字节为单位进行内存分配。

3)new在申请单个类型变量时可进行初始化。malloc不具备内存初始化的特性。

3、C++动态分配内存异常机制

如我们分配一个很大的内存空间,会出现栈满,程序产生异常,程序崩溃。则需要引入异常机制。C ++提供了两种标准机制来检查分配是否成功。

1)处理异常,在分配失败时抛出bad_alloc类型的异常。如果抛出此异常并且未由特定处理程序处理,则程序执行将终止。

例如,

#include <iostream>
#include <new> // for std::bad_alloc
using namespace std;

int main() {
    try {
        // 尝试分配一块很大的内存
        // 可能超出系统可用内存
        int* ptr = new int[1000000000000]; 
    } catch (const std::bad_alloc& e) {
        // 捕获异常并处理
        cout << "Memory allocation failed: "
        << e.what() << endl;
    }

    return 0;
}

2)使用nothrow,内存分配失败时,而不是抛出bad_alloc异常或终止程序,new返回的指针是空指针,程序继续正常执行 。

例如,

#include <iostream>
#include <new> // for std::nothrow
using namespace std;

int main() {
    // 使用 nothrow 分配内存
    // 可能超出系统可用内存
    int* ptr = new(std::nothrow) int[1000000000000];

    if (ptr == nullptr) {
        // 检查指针是否为空
        cout << "Memory allocation failed!" << endl;
    } else {
        cout << "Memory allocation succeeded!" << endl;
        delete[] ptr; // 释放内存
    }

    return 0;
}

推荐文档