int* p = new int[5]; int *p = new int[5]();delete[] p; delete p;区别是什么?

int main() {
    int *p = new int[5]; // 分配包含5个整数的数组内存

    // 初始化数组元素
    for (int i = 0; i < 5; i++) {
        p[i] = i * 10;
    }

    // 试图使用 delete p; 来释放数组内存
    delete p;

    delete[] p;

    // 打印数组元素
    for (int i = 0; i < 5; i++) {
        std::cout << "p[" << i << "] = " << p[i] << std::endl;
    }

    return 0;
}

代码如上,在delete p;的时候会发生什么问题,又是什么原因导致的?

首先,需要知道delete在底层都做了什么:

  1. 调用析构函数:如果 p 指向一个对象(而不是基本数据类型的数组),C++ 运行时将调用这个对象的析构函数。对于基本数据类型(如 int、float 等)或者数组,析构函数不会被调用,因为它们没有析构函数。

  2. 内存回收delete 操作将释放 p 指向的内存块。这块内存之后可能被操作系统回收,或者留待将来重新分配。

  3. 清理内部管理信息:C++ 运行时维护了一些内部数据结构来管理动态分配的内存。delete 操作将更新这些数据结构,标记相应的内存块为“可用”

而int *p = new int[5];中的p是指向该数组首地址的指针,如果你是用delete p;其实只是做了:

        1. 删除了p这个对象

        2. 回收p所指向内存(数组首个元素)

        3. 清理内部管理信息

所以,数组剩下的元素是没有被清理回收的,我用ide输出了结果,发现delete p的结果如下:

p[0] = 1490466881
p[1] = 5
p[2] = -720962155
p[3] = 305593618
p[4] = 40

都是一些奇怪的值,也能证明刚才提到的delete p所发生的的事情。

如果你分配了数组,要进行释放,使用delete[] p;  p = nullptr;如下:

int main() {
    int *p = new int[5]; // 分配包含5个整数的数组内存

    // 初始化数组元素
    for (int i = 0; i < 5; i++) {
        p[i] = i * 10;
    }


    delete[] p;
    p = nullptr;

    // 打印数组元素
    for (int i = 0; i < 5; i++) {
        std::cout << "p[" << i << "] = " << p[i] << std::endl;
    }

    return 0;
}

那delete[] p;底层实现是怎么做的呢?以下:

  1. 查找数组大小:运行时使用 p 指针回退到数组大小存储的位置,获取数组的大小。

  2. 调用析构函数:如果数组元素是类对象,并且有析构函数,运行时将为数组中的每个元素调用析构函数。运行时知道数组的大小,所以它可以正确地循环通过每个元素来调用析构函数。

  3. 内存回收:运行时释放整个数组占用的内存块,包括存储数组大小的那部分内存。

  4. 清理内部管理信息:运行时更新其内部数据结构,标记相应的内存块为“可用”。

那代码中还有一个问题,我们一般new会调用构造函数,代码如下:

int *p = new int[5]; 
int *p = new int[5](); 

以上两个有什么区别呢?简单来说:

  1. int *p = new int[5];

    • 不会初始化数组中的元素。拥有未定义的值,取决于内存初始状态。
    • 必须在使用数组之前手动初始化每个元素。
  2. int *p = new int[5]();

    • 会将数组中的每个元素初始化为0。
    • “值初始化”(value-initialization)。当你在 new 表达式后面加上一对空括号 () 时,触发值初始化。对于基本数据类型如 int,初始化为0。
    • 确保数组的每个元素都被初始化为一个确定的值,减少了出错。

大概是这些~,有帮助就点个赞吧!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值