C++ new和malloc

目录

new

        1.什么是new?

        2.new的基本用法

               分配单个对象

               分配数组

                带参数的构造函数

        3.new的高级特性

                自定义内存分配器

                抛出异常处理

                无抛出版本

        4.new的使用注意事项

malloc

        1.什么是malloc?

        2.函数声明

        3.实例用法

new和malloc的区别


new

1.什么是new?

        C++中,new是一个运算符,用于动态分配内存,返回一个指向分配内存的指针,通常和delete运算符一起使用,用于在堆上分配和释放内存。

        同C语言的malloc()不同,new通过调用构造函数去初始化对象,当使用delete()释放内存时,会调用对象的析构函数,而对象的生命周期从构造函数完成时开始,到析构函数完成时结束。

2.new的基本用法

        a. 分配单个对象

new(n) 分配一个大小的内存空间,以括号中的值来初始化这个变量

#include<bits/stdc++.h>
using namespace std;

int main(){
    int *a=new int(5); //动态分配一个int类型的内存,并初始化为5 
    cout<<sizeof(a)<<" "<<a<<endl; //输出指针a的大小和地址 
    cout<<sizeof(*a)<<" "<<*a<<endl; //输出指针a指向的对象的大小和值 
    delete a;//释放动态分配的内存,释放单个对象
 return 0;
}

        b.分配数组

new[ ] 分配n个大小的内存空间,用默认构造函数初始化这些变量

#include<bits/stdc++.h>
using namespace std;

int main(){
    int *a=new int[5];
    for(int i=1;i<=5;++i){
        a[i]=i;
    }
    for(int i=1;i<=5;++i){
        cout<<a[i]<<" ";
    }
    delete[] a;//释放对象数组 
    return 0;
}

注意:

  • 使用new动态分配的内存必须使用delete或delete[ ]释放
  • 当使用new运算符定义一个多维数组或数组对象时,它产生一个指向第一个元素的指针,返回的类型保持除了最左边维数外的所有维数。
    • int (*a)[3][5] = new int[5][3][10]; 返回的是一个指向二维数组int[3][10]这种类型的指针int (*)[3][5]

        c.带参数的构造函数

在C++中,使用new创建对象时,可以通过构造函数传递参数来初始化对象。

#include<bits/stdc++.h>
using namespace std;
class MyClass{
    private:
        int value;
    public:
        //带参数的构造函数,使用初始化列表 
        MyClass(int v):value(v){
            cout<<"参数构造value:"<<value<<endl;
        }
};
int main(){
    MyClass* a=new MyClass(5);
    delete a;
    return 0;
}

3.new的高级特性

        a.自定义内存分配器

        通过重载全局或类级别的poerator new来实现自定义分配逻辑

#include <iostream>
#include <cstdlib>
#include <new> // 包含 std::bad_alloc

// 自定义全局 new 操作符
void* operator new(size_t size) {
    std::cout << "Custom new called for size: " << size << std::endl;
    void* ptr = std::malloc(size);
    if (!ptr) {
        throw std::bad_alloc(); // 如果分配失败,抛出异常
    }
    return ptr;
}

// 自定义全局 delete 操作符
void operator delete(void* ptr) noexcept {
    std::cout << "Custom delete called" << std::endl;
    std::free(ptr);
}

        b.抛出异常处理

        当new无法为请求分配足够的内存时,默认情况下会抛出一个std::bad_alloc异常

 try {
        // 尝试分配一个非常大的内存块
        int* largeArray = new int[1000000000000];
        std::cout << "Memory allocation succeeded" << std::endl;
        delete[] largeArray; // 释放内存
    } catch (const std::bad_alloc& e) {
        std::cerr << "Memory allocation failed: " << e.what() << std::endl;
    }

        c.无抛出版本

        如果不希望new抛出异常,而是返回空指针,可以使用nothrow修饰符
MyClass* obj = new (std::nothrow) MyClass(10);
if (obj == nullptr) {
    std::cerr << "Memory allocation failed" << std::endl;
}

4.new的使用注意事项

        a. new和delete总是成对出现:使用了new分配内存之后,就应该考虑如何以及何时使用delete去释放它,避免内存泄漏

        b. 优先考虑智能指针:C++标准库提供了几种智能指针类型,最常用的就是std::unique_ptr 和 std::shared_ptr。智能指针可以有效避免内存泄漏和悬空指针的问题,智能指针通过RAII机制,在对象生命周期结束时自动释放资源。

        c. 避免频繁使用动态分配:动态分配虽然灵活,但效率较低且容易导致内存碎片化,尽可能将对象放到栈上。

malloc

1.什么是malloc?

        头文件为#include的 C库函数void *malloc(size_t size)分配所需空间,并返回一个指向它的指针。

2.函数声明

    void *malloc(size_t size)

  • size:内存块大小,以字节为单位
  • 返回值:返回一个指针,指向已分配大小的内存块;如果分配失败则返回空指针NULL
  • 释放:当内存不在使用时,用使用free()函数释放

3.实例用法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    //初始化为hello
    char* str = (char*)malloc(6);
 //(char*)用于显示转换malloc返回的void*类型的指针
    strcpy(str, "hello");
    printf("str:%s;str的地址:%u\n", str,str);

    //重新分配
    str = (char*)realloc(str,15);
    strcpy(str, "hello,world");
    printf("str:%s;str的地址:%u\n", str, str);
    return(0);
}

代码结果展示:

str:hello;str的地址:2048660064

str:hello,world;str的地址:2048659424

new和malloc的区别

  • new的返回值不需要强制转换,malloc的返回值需要强制转换
  • new是运算符可以重载,malloc是库函数,不能重载
  • new不需要传入想要申请的具体字节个数,malloc需要传入想要申请的具体字节个数
  • new申请失败会抛出异常,malloc申请失败会返回空
  • 如果给一个类分配堆区内存new会先调用malloc分配内存,然后再调用构造函数给成员变量赋值
  • new申请的堆区内存需要delete释放,delete先调用析构函数再调用free(free也是C语言库函数和malloc是配套的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值