c++中new操作符的具体使用

 更新时间:2026年01月08日 10:23:47   作者:风kkk  
本文主要介绍了c++中new操作符的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在 C++ 中,new 是一个关键字(操作符),主要用于在堆内存(Heap) 上进行动态内存分配

与 C 语言中的 malloc 不同,new 不仅分配内存,还会自动调用对象的构造函数来初始化对象。

以下是关于 new 的详细介绍,包括基本用法、原理、高级用法以及现代 C++ 的最佳实践。

1. 基本用法

1.1 分配单个对象

当使用 new 分配单个对象时,它返回指向该类型的指针。

// 1. 分配一个 int,未初始化(值可能是随机的)
int* p1 = new int; 

// 2. 分配一个 int,并初始化为 10
int* p2 = new int(10); 

// 3. 分配一个类对象,自动调用构造函数
MyClass* obj = new MyClass(); 

// 使用完毕后,必须使用 delete 释放
delete p1;
delete p2;
delete obj;
/*使用new从堆中分配一个int大小内存,不同于malloc,new会返回一个具体类型的指针,而不是void* */
int* fun1()
{
    /*这里返回的虽然是一个局部变量指针,但因为是从堆中分配,退出函数后这块内存不会被销毁*/
    return new int;
}

/*使用new操作符分配一个int类型内存,并初始化为10 */
int* fun2()
{
    /*分配一个int类型内存,赋值为10*/
    return new int(10);
}

/*使用new分配一个类对象内存,在分配内存时会调用这个类的构造函数初始化这块内存*/
// my_class* fun3()
// {
//     return new my_clash();
// }

/*使用new分配一个数组*/
int* fun4()
{
    return new int[10];
}


int main()
{
    int *p1 = fun1();
    *p1 = 20;
    cout << "p1指向的值为:" << *p1 << endl;
    delete p1;

    int *p2 = fun2();
    cout << "p2指向的值为:" << *p2 << endl;
    delete p2;

    // my_clash *p3 = fun3();
    // delete p3;

    int *p4 = fun4();
    cout << "p4指向的数组为:";
    for (int i = 0; i < 10;i++)
    {
        p4[i] = i;
        cout << p4[i] << " ";
    }
    cout << endl;
    system("pause");
    return 0;
}

1.2 分配数组

使用 new 也可以分配连续的内存空间(数组)。

// 分配一个包含 10 个整数的数组
int* arr = new int[10];

// 访问数组元素
arr[0] = 5;

// 注意:释放数组时必须使用 delete[] (带方括号)
delete[] arr; 

2.new与malloc的区别 (面试常考)

这是理解 C++ 内存管理的关键点:

特性new / deletemalloc / free
属性C++ 关键字 (操作符)C 语言标准库函数
初始化分配内存 + 调用构造函数仅分配内存,不初始化
返回值返回具体类型的指针 (无需强转)返回 void* (需要强转)
大小计算自动计算类型大小需要手动计算字节数 (sizeof)
失败处理抛出 std::bad_alloc 异常返回 NULL
重载允许重载不允许

3. 内存分配失败的处理

当堆内存耗尽时,默认情况下 new 会抛出异常,而不是返回空指针。

3.1 标准行为(抛出异常)

try {
    int* bigArray = new int[1000000000000]; // 试图分配巨大的内存
} catch (const std::bad_alloc& e) {
    std::cout << "内存分配失败: " << e.what() << std::endl;
}

3.2 不抛出异常(std::nothrow)

如果你希望像 C 语言那样在失败时返回 nullptr,可以使用 std::nothrow 版本:

#include <new> // 必须包含

int* p = new(std::nothrow) int[1000000000000];
if (p == nullptr) {
    std::cout << "内存分配失败,指针为空" << std::endl;
} else {
    delete[] p;
}

4. 进阶:Placement New (定位 new)

placement new 允许你在已经分配好的内存上构造对象。这通常用于内存池、嵌入式系统或高性能库中,以避免频繁的内存分配/释放开销。

#include <new>

char buffer[sizeof(MyClass)]; // 预先分配的栈内存或堆内存

// 在 buffer 的地址上调用 MyClass 的构造函数
MyClass* p = new (buffer) MyClass(123); 

// 注意:对于 Placement New,不能使用 delete p
// 必须显式调用析构函数
p->~MyClass();

// 如果 buffer 是堆内存,最后释放 buffer
// delete[] buffer; 

5. 常见陷阱:内存泄漏 (Memory Leak)

使用 new 最大的风险就是忘记 delete

void badFunction() {
    int* ptr = new int(5);
    // ... 做一些操作
    // 函数结束,ptr 变量销毁了,但它指向的堆内存没有释放!
    // 这就是内存泄漏。
}

此外,配对错误也是常见问题:

  • new 必须配对 delete
  • new[] 必须配对 delete[]

如果不匹配(例如对数组使用 delete),会导致未定义行为(通常是程序崩溃)。

6. 现代 C++ 最佳实践 (C++11 及以后)

在现代 C++ 开发中,极其不推荐直接使用裸指针(Raw Pointer)和 new/delete

应该使用 RAII (资源获取即初始化) 原则和 智能指针 来自动管理内存。

6.1std::unique_ptr(独占所有权)

这是最常用的智能指针。当指针超出作用域时,会自动释放内存。

#include <memory>

// C++14 推荐写法:使用 make_unique
auto ptr = std::make_unique<MyClass>(10); 

// 不需要调用 delete,由 ptr 的析构函数自动处理
ptr->doSomething();

6.2std::shared_ptr(共享所有权)

当多个指针需要指向同一个对象时使用。使用引用计数,当计数归零时自动释放。

#include <memory>

auto ptr1 = std::make_shared<MyClass>(20);
auto ptr2 = ptr1; // 引用计数 +1

// 当 ptr1 和 ptr2 都销毁时,内存才会被释放

总结

  1. new 用于在堆上分配内存并初始化对象。
  2. 必须使用 delete 释放内存,否则会导致泄漏。
  3. 数组分配需用 new[]delete[]
  4. 最佳实践:尽量避免直接使用 new,改用 std::make_uniquestd::make_shared 等智能指针,以确保内存安全。

到此这篇关于c++中new操作符的具体使用的文章就介绍到这了,更多相关C++ new操作符 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C和C++ const的声明差异

    C和C++ const的声明差异

    本文给大家简单汇总了下C语言的const与C++的const的声明差异,非常的简单,也很实用,有需要的小伙伴可以参考下
    2016-03-03
  • C++类与对象之运算符重载详解

    C++类与对象之运算符重载详解

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的
    2021-10-10
  • C++遍历某个文件夹下面的子文件夹及其所有文件

    C++遍历某个文件夹下面的子文件夹及其所有文件

    这篇文章主要介绍了C++获取某个文件夹下面的子文件夹及其所有文件,需要的朋友可以参考下
    2021-07-07
  • C语言快速实现扫雷小游戏

    C语言快速实现扫雷小游戏

    这篇文章主要为大家详细介绍了C语言实现扫雷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • C语言实现学生成绩等级划分的方法实例

    C语言实现学生成绩等级划分的方法实例

    这篇文章主要给大家介绍了关于C语言实现学生成绩等级划分的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • C++中的拷贝构造函数详解

    C++中的拷贝构造函数详解

    大家好,本篇文章主要讲的是C++中的拷贝构造函数详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • C语言学习笔记之VS2022安装使用教程

    C语言学习笔记之VS2022安装使用教程

    这篇文章主要介绍了C语言学习笔记之VS2022安装使用教程,在VS2022中,在使用scanf函数编译出错,本文给大家提到了解决方法,需要的朋友可以参考下
    2022-05-05
  • C++特殊类设计与类型转换详细代码示例

    C++特殊类设计与类型转换详细代码示例

    在C++编程语言中,类类型转换操作符是一种特殊的功能,允许我们把一个类的对象转换为其他类型,如内置类型、类类型或者由类型别名定义的类型,这篇文章主要介绍了C++特殊类设计与类型转换的相关资料,需要的朋友可以参考下
    2026-01-01
  • Windows下ncnn环境配置教程详解(VS2019)

    Windows下ncnn环境配置教程详解(VS2019)

    这篇文章主要介绍了Windows下ncnn环境配置(VS2019),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C语言 function recursion函数递归详解

    C语言 function recursion函数递归详解

    递归指的是在函数的定义中使用函数自身的方法,举个例子: 从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,循环下去
    2021-10-10

最新评论